【问题标题】: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。如果我可以在发出信号后立即等待同一个事件对象,那么……我可以保存一个事件对象。

如果你问我为什么不只使用一个线程,它们是在不同的进程中。

【问题讨论】:

    标签: c++ windows synchronization


    【解决方案1】:

    当服务员被释放时,该事件变为无信号状态。无法保证在调用SetEvent 返回之前释放服务员。

    【讨论】:

    • 好的,那么是什么取消了事件的信号呢?不能是事件设置线程,因为有可能在 SetEvent() 返回时服务员没有被释放,而当服务员被释放时事件变得无信号。不能是服务员线程,因为如果没有释放它就不能运行。
    • 哦,对了。我一直认为那些事件的东西有些奇怪......
    • 确实,如果你编写一个测试程序尝试用单个事件来做,你会发现你经常看到一个线程消耗它自己的信号(而不是让另一个线程消耗它) .
    【解决方案2】:

    一般来说,不会。到那时,另一个线程可能已经发出信号,如果没有线程等待,它将保持设置状态。在只有两个线程的情况下,也许你会没事的。

    你为什么还要对这样的“优化”感到厌烦。使用两个事件会更容易调试。

    多线程、线程间和进程间通信已经够难了。你不应该增加更多的复杂性。

    【讨论】:

    • 或多或少只是好奇,因为内核似乎实际上是这样工作的。但我想知道它是否是由比实现更多的东西来强制执行的。
    • Windows 事件的整体行为似乎有点奇怪。 @Raymond Chen 认为内核线程以及设置器/服务员都参与其中,我不打算争论那个。如果您想安全地“乒乓”两个线程,我建议使用两个信号量。
    • 好像没有专门的线程来管理事件。内核在所有线程上运行。 (即使在有两个线程的情况下,你也可能不行,因为线程 B 可能设法等待事件线程 A 被唤醒。例如,线程 A 可能被内核 APC 劫持并且暂时无法为该活动提供服务。)
    • @RaymondChen 我得到了照片。
    • 谢谢,@RaymondChen - 我会坚持使用信号量。至少 Windows 线程同步不支持某些其他操作系统的“虚假唤醒”功能......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多