【问题标题】:Difference between event object and condition variable事件对象和条件变量的区别
【发布时间】:2010-11-15 23:15:58
【问题描述】:

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

【问题讨论】:

    标签: c++ multithreading winapi synchronization


    【解决方案1】:

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

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

    就功能而言,将条件变量视为两个对象协同工作的逻辑组合——keyed event 和锁定对象。当条件变量进入睡眠状态时,它会重置事件,释放锁,等待事件发出信号,然后重新获取锁。例如,如果您使用临界区作为锁定对象,SleepConditionalVariableCS() 类似于对ResetEvent()LeaveCriticalSection()WaitForSingleObject()EnterCriticalSection() 的一系列调用。而如果您使用 SRWL 作为锁,SleepConditionVariableSRW() 类似于对ResetEvent()ReleaseSRWLock...()WaitForSingleObject()AcquireSRWLock...() 的一系列调用。

    【讨论】:

    • 我不明白,如果一个 CS 中包含一个事件,那么你怎么能声称它受到可用内存而不是系统中可用事件数量的限制?
    • 我没有说 CS 包含一个 ACTUAL 事件对象,我所说的是“从技术上讲,这不是条件变量在内部实际执行的操作”,仅 IOW就像它使用事件一样,但它可能不会。 CS 如何等待的细节对于操作系统的实现来说是私有的。例如,在SleepConditionVariableCS() 的情况下,它更有可能使用SleepEx(),并被超时或来自WakeConditionVariable() 的APC 唤醒。我更新了答案以反映这一点。
    • 在阅读了walkingbear 的回答后,该实现很可能使用keyed event 作为可等待对象。这样,多个 CS 使用共享单个内核事件对象,该对象始终可用并且可以由单独的线程单独等待。
    • CS 似乎确实包含一个实际的信号量(参见WinNT.hRTL_CRITICAL_SECTION 的定义),但我刚刚意识到我误读了您的答案——您说的是CV,而不是CS。事实上,一个关键事件是最有可能的。 CS 肯定需要一个事件或信号量或其他东西,以便它可以在需要时进入内核等待,但 CV 似乎不需要。
    • 是的,抱歉,我指的是 CV,而不是 CS。是的,CS(不是 CV)可以包含专用事件对象(在需要时分配),或者如果无法分配专用事件,则可以包含全局键控事件。
    【解决方案2】:

    最显着的区别是Event对象是内核对象,只要进程/线程试图获取时它还活着,就可以跨进程共享,相反,Condition变量是轻量级的用户态对象(仅与指针大小相同,使用后没有任何额外的释放)并且具有更好的性能。

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

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

    【讨论】:

      【解决方案3】:

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

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

      来自MSDN documentation on event objects

      其他进程中的线程可以打开一个 处理现有事件对象 在调用 打开事件函数。

      【讨论】:

      • 不,Remy Lebeau 更接近真相。条件变量是最近从 Unix 导入 Windows 的东西。事件对象是对条件的苍白模仿。事实上,仅在给定事件对象和互斥体的情况下实现 Condition Var 并非易事。见cse.wustl.edu/~schmidt/win32-cv-1.html
      猜你喜欢
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 2012-10-27
      • 2014-10-07
      • 2012-09-20
      相关资源
      最近更新 更多