c++ - 等待事件的线程并不总是捕获事件信号

标签 c++ windows multithreading event-handling

我有一个应用程序,其中多个线程等待同一个事件对象发出信号。我看到的问题似乎是一种竞争条件,因为有时某些线程的等待状态 (WaitForMultipleObjects) 由于事件信号而返回,而其他线程的等待状态显然看不到事件信号,因为他们没有返回。这些事件是使用 CreateEvent 作为手动重置事件对象创建的。

我的应用程序处理这些事件,以便在事件对象发出信号时,其“所有者”线程负责重置事件对象的信号状态,如以下代码片段所示。等待同一事件的其他线程不会尝试重置其信号状态。

switch ( dwObjectWaitState = ::WaitForMultipleObjects( i, pHandles, FALSE, INFINITE ) )
{
case WAIT_OBJECT_0 + BAS_MESSAGE_READY_EVT_ID:
    ::ResetEvent( pHandles[BAS_MESSAGE_READY_EVT_ID] );
    /* handles the event */
    break;
}

换句话说,我看到的问题似乎与 Remarks section for PulseEvent on the MSDN website 中描述的内容有关。 :

If the call to PulseEvent occurs during the time when the thread has been removed from the wait state, the thread will not be released because PulseEvent releases only those threads that are waiting at the moment it is called. Therefore, PulseEvent is unreliable and should not be used by new applications. Instead, use condition variables.

如果发生这种情况,我能看到的唯一解决方案是让每个线程向该对象的所有者线程注册其对给定事件对象的使用,以便所有者线程可以确定何时可以安全地重置事件对象的信号状态。

有更好的方法吗?谢谢。

最佳答案

是的,有更好的方法:

[...] Instead, use condition variables.

http://msdn.microsoft.com/en-us/library/ms682052(v=vs.85).aspx

寻找WakeAllConditionVariable具体

关于c++ - 等待事件的线程并不总是捕获事件信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5916894/

相关文章:

c++ - 共享指针和多线程

java - 使用进程 ID 和线程 ID 命名目录

c++ - directx 旋转 C++

Java JNI错误java.lang.UnsatisfiedLinkError : xxxx()V

c++ - 是什么让指针的这种用法不可预测?

c++ - 在 OpenCV 中捕获和显示视频

windows - GVim Win32 中的仅键盘列 block 选择,或者为什么包含 mswin.vim 时 Ctrl-Q 不模拟 Ctrl-V?

asp.net - ColdFusion 无法模拟 Windows 用户来访问目录大小 - 也许是 ASP.NET

c++ - 从 'OLE_HANDLE' 转换为 'HICON' 的正确方法是什么?

java - 线程池不接受新任务