互斥、临界区、信号灯、事件
2008-02-16 16:23
204 查看
互斥,每次只能有一个线程可以通过Wait
信号灯,最多只能同时有N个线程可以通过Wait
临界区,每次只能一个线程可以通过Enter
事件。。。通过Wait来进行判定时间的发生
令:摘抄了葡萄架上的牵牛花同志的BLOG里对M与C的表格式总结,谢谢他的那篇文章,我直接拉了过来。
[align=left]Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用绿色表示)。[/align]
[align=left] [/align]
[align=left]下面是一些补充:[/align]
[align=left]l 请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的可能就越小。[/align]
[align=left]l 每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也同样。若你把这个问题和Win32 structured exception或C++ exception一起考虑,你会发现问题并不是那么简单。自定义一个封装类可能是一种解决方案,以Critical Section为例的代码如下所示:[/align]
[align=left]class csholder[/align]
[align=left]{[/align]
[align=left] CRITICAL_SECTION *cs;[/align]
[align=left]public:[/align]
[align=left] csholder(CRITICAL_SECTION *c): cs(c)[/align]
[align=left] { EnterCriticalSection(cs); }[/align]
[align=left] ~csholder() { LeaveCriticalSection(cs); }[/align]
[align=left]};[/align]
[align=left] [/align]
[align=left]CRITICAL_SECTION some_cs;[/align]
[align=left]void foo()[/align]
[align=left]{[/align]
[align=left] // ...[/align]
[align=left] csholder hold_some(&some_cs);[/align]
[align=left] [/align]
[align=left] // ... CS protected code here[/align]
[align=left] [/align]
[align=left] // at return or if an exception happens[/align]
[align=left] // hold_some's destructor is automatically called[/align]
[align=left]}[/align]
[align=left]l 根据你的互斥范围需求的不同,把Mutex或Critical Section定义为类的成员变量,或者静态类变量。[/align]
[align=left]l 若你想限制访问的全局变量只有一个而且类型比较简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列函数来保证一个线程写多个线程读。[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]本文主要参照了Jeffrey Richter的《Programming Applications for Microsoft Windows, 4th Ed.》。[/align]
信号灯,最多只能同时有N个线程可以通过Wait
临界区,每次只能一个线程可以通过Enter
事件。。。通过Wait来进行判定时间的发生
令:摘抄了葡萄架上的牵牛花同志的BLOG里对M与C的表格式总结,谢谢他的那篇文章,我直接拉了过来。
Mutex 和 Critical Section 的异同 - 表格形式,一目了然
Posted on Tuesday, July 11, 2006 4:02 PM #C & C++[align=left]Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用绿色表示)。[/align]
Mutex | Critical Section | |
性能和速度 | 慢。 Mutex 是内核对象,相关函数的执行 (WaitForSingleObject, ReleaseMutex)需要用户模式(User Mode)到内核模式(Kernel Mode)的转换,在x86处理器上这种转化一般要发费600个左右的 CPU指令周期。 | 快。 Critical Section本身不是内核对象,相关函数(EnterCriticalSection,LeaveCriticalSection)的调用一般都在用户模式内执行,在x86处理器上一般只需要发费9个左右的 CPU指令周期。只有当想要获得的锁正好被别的线程拥有时才会退化成和Mutex一样,即转换到内核模式,发费600个左右的 CPU指令周期。 |
能否跨越进程(Process)边界 | 可以 | 不可 |
定义写法 | HANDLE hmtx; | CRITICAL_SECTION cs; |
初始化写法 | hmtx= CreateMutex (NULL, FALSE, NULL); | InitializeCriticalSection(&cs); |
结束清除写法 | CloseHandle(hmtx); | DeleteCriticalSection(&cs); |
无限期等待的写法 | WaitForSingleObject (hmtx, INFINITE); | EnterCriticalSection(&cs); |
0等待(状态检测)的写法 | WaitForSingleObject (hmtx, 0); | TryEnterCriticalSection(&cs); |
任意时间等待的写法 | WaitForSingleObject (hmtx, dwMilliseconds); | 不支持 |
锁释放的写法 | ReleaseMutex(hmtx); | LeaveCriticalSection(&cs); |
能否被一道用于等待其他内核对象 | 可以(使用WaitForMultipleObjects,WaitForMultipleObjectsEx,MsgWaitForMultipleObjects,MsgWaitForMultipleObjectsEx等等) | 不可 |
当拥有锁的线程死亡时 | Mutex变成abandoned状态,其他的等待线程可以获得锁。 | Critical Section的状态不可知(undefined),以后的动作就不能保证了。 |
自己会不会锁住自己 | 不会(对已获得的Mutex,重复调用WaitForSingleObject不会锁住自己。但最后你别忘了要调用同样次数的ReleaseMutex) | 不会(对已获得的Critical Section,重复调用EnterCriticalSection不会锁住自己。但最后你别忘了要调用同样次数的LeaveCriticalSection) |
[align=left]下面是一些补充:[/align]
[align=left]l 请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的可能就越小。[/align]
[align=left]l 每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也同样。若你把这个问题和Win32 structured exception或C++ exception一起考虑,你会发现问题并不是那么简单。自定义一个封装类可能是一种解决方案,以Critical Section为例的代码如下所示:[/align]
[align=left]class csholder[/align]
[align=left]{[/align]
[align=left] CRITICAL_SECTION *cs;[/align]
[align=left]public:[/align]
[align=left] csholder(CRITICAL_SECTION *c): cs(c)[/align]
[align=left] { EnterCriticalSection(cs); }[/align]
[align=left] ~csholder() { LeaveCriticalSection(cs); }[/align]
[align=left]};[/align]
[align=left] [/align]
[align=left]CRITICAL_SECTION some_cs;[/align]
[align=left]void foo()[/align]
[align=left]{[/align]
[align=left] // ...[/align]
[align=left] csholder hold_some(&some_cs);[/align]
[align=left] [/align]
[align=left] // ... CS protected code here[/align]
[align=left] [/align]
[align=left] // at return or if an exception happens[/align]
[align=left] // hold_some's destructor is automatically called[/align]
[align=left]}[/align]
[align=left]l 根据你的互斥范围需求的不同,把Mutex或Critical Section定义为类的成员变量,或者静态类变量。[/align]
[align=left]l 若你想限制访问的全局变量只有一个而且类型比较简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列函数来保证一个线程写多个线程读。[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]本文主要参照了Jeffrey Richter的《Programming Applications for Microsoft Windows, 4th Ed.》。[/align]
相关文章推荐
- 线程的创建、管理 与 使用信号灯、互斥量、临界区、事件进行线程同步或互斥
- 线程同步的三种方法(互斥,事件,临界区) 之三 使用事件对象
- VC下线程同步的三种方法(互斥、事件、临界区)/(转)
- 线程同步与临界区对象、互斥对象、事件对象
- 临界区、互斥、信号量、事件区别
- WaitForSingleObject与事件、信号量、互斥、临界区的用法
- VC下线程同步的三种方法(互斥、事件、临界区)
- 同步互斥,信号量,互斥量,事件,临界区
- 临界区 事件 互斥锁 信号量 编程总结
- 互斥锁 临界区 信号量 事件的区别
- 临界区、互斥、信号量、事件区别
- 第一章——扩展——临界区-互斥信号量-事件
- VC下线程同步的三种方法(互斥、事件、临界区)
- 进程与线程;同步与互斥:事件,信号量,临界区,互斥量
- 临界区、互斥、信号量、事件区别
- VC下线程同步的三种方法(互斥、事件、临界区)
- 临界区,互斥事件,互斥对象,信号量的区别
- C++多线程 互斥锁 信号量 事件 临界区
- VC下线程同步的三种方法(互斥、事件、临界区)
- 临界区、事件、互斥量、 信号量--四种控制多线程同步与互斥的方法