事件对象和条件变量之间的区别

时间:2009-07-31 23:55:33

标签: c++ multithreading winapi synchronization

事件对象和条件变量之间有什么区别? 我在WIN32 API的上下文中询问。

3 个答案:

答案 0 :(得分:22)

事件对象是内核级对象。它们可以跨进程边界共享,并且在所有Windows操作系统版本上都受支持。如果需要,它们可以用作共享资源的独立锁。由于它们是内核对象,因此操作系统对可以一次分配的可用事件数量有限制。

条件变量是用户级对象。它们不能跨进程边界共享,并且仅在Vista / 2008及更高版本上受支持。它们不作为自己的锁,但需要单独的锁与它们相关联,例如关键部分。由于它们是用户对象,因此可用变量的数量受可用内存的限制。当条件变量进入休眠状态时,它会自动释放指定的锁定对象,以便另一个线程可以获取它。当条件变量唤醒时,它会再次自动重新获取指定的锁定对象。

在功能方面,将条件变量视为两个对象一起工作的逻辑组合 - keyed event和锁定对象。当条件变量进入休眠状态时,它会重置事件,释放锁定,等待事件发出信号,然后重新获取锁定。例如,如果您使用关键部分作为锁定对象,则SleepConditionalVariableCS()类似于对ResetEvent()LeaveCriticalSection()WaitForSingleObject()和{{1}的一系列调用}。如果您使用SRWL作为锁定,EnterCriticalSection()类似于对SleepConditionVariableSRW()ResetEvent()ReleaseSRWLock...()WaitForSingleObject()的一系列调用。

答案 1 :(得分:2)

它们非常相似,但事件对象跨进程边界工作,而条件变量则不工作。来自MSDN documentation on condition variables

  

条件变量是用户模式   无法共享的对象   过程

来自MSDN documentation on event objects

  

其他进程中的线程可以打开   处理现有的事件对象   在调用时指定其名称   OpenEvent函数。

答案 2 :(得分:1)

最重要的区别是Event对象是一个内核对象,只要它在进程/线程尝试获取时处于活动状态,就可以跨进程共享,相反,Condition变量是一个用户模式对象,它很轻(只有与指针相同的大小,并且在使用它之后没有其他任何东西可以释放)并且具有更好的性能。

通常,条件变量通常与锁一起使用,因为我们需要保持数据正确同步。在考虑条件变量时,我们将其视为自Vista以来改进的键控事件。

Joe duffy有一篇博文http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/,解释了更详细的信息。