Windows 的 SetEvent 的确切行为是啥?
Posted
技术标签:
【中文标题】Windows 的 SetEvent 的确切行为是啥?【英文标题】:What is the exact behavior of Windows' SetEvent?Windows 的 SetEvent 的确切行为是什么? 【发布时间】:2012-04-24 13:03:37 【问题描述】:我有一个自动重置事件对象,并且有一个线程在等待它。如果现在我调用SetEvent,是否可以保证SetEvent返回时事件对象是无信号的?
我有两个线程以 A-B-A-B-... 方式运行。一旦 A 唤醒 B,A 就会开始等待 B。如果我可以在发出信号后立即等待同一个事件对象,那么……我可以保存一个事件对象。
如果你问我为什么不只使用一个线程,它们是在不同的进程中。
【问题讨论】:
【参考方案1】:当服务员被释放时,该事件变为无信号状态。无法保证在调用SetEvent
返回之前释放服务员。
【讨论】:
好的,那么是什么取消了事件的信号呢?不能是事件设置线程,因为有可能在 SetEvent() 返回时服务员没有被释放,而当服务员被释放时事件变得无信号。不能是服务员线程,因为如果没有释放它就不能运行。 哦,对了。我一直认为那些事件的东西有些奇怪...... 确实,如果你编写一个测试程序尝试用单个事件来做,你会发现你经常看到一个线程消耗它自己的信号(而不是让另一个线程消耗它) .【参考方案2】:一般来说,不会。到那时,另一个线程可能已经发出信号,如果没有线程等待,它将保持设置状态。在只有两个线程的情况下,也许你会没事的。
你为什么还要对这样的“优化”感到厌烦。使用两个事件会更容易调试。
多线程、线程间和进程间通信已经够难了。你不应该增加更多的复杂性。
【讨论】:
或多或少只是好奇,因为内核似乎实际上是这样工作的。但我想知道它是否是由比实现更多的东西来强制执行的。 Windows 事件的整体行为似乎有点奇怪。 @Raymond Chen 认为内核线程以及设置器/服务员都参与其中,我不打算争论那个。如果您想安全地“乒乓”两个线程,我建议使用两个信号量。 好像没有专门的线程来管理事件。内核在所有线程上运行。 (即使在有两个线程的情况下,你也可能不行,因为线程 B 可能设法等待事件在线程 A 被唤醒。例如,线程 A 可能被内核 APC 劫持并且暂时无法为该活动提供服务。) @RaymondChen 我得到了照片。 谢谢,@RaymondChen - 我会坚持使用信号量。至少 Windows 线程同步不支持某些其他操作系统的“虚假唤醒”功能......以上是关于Windows 的 SetEvent 的确切行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章
setEvent 在没有 ResetEvent 的情况下被调用
如何在 Windows 窗体 (C#) 中设置列表框的确切高度?
单个 SetEvent() 能否触发多个 WaitForSingleObject()