在多个自动重置事件上使用WaitForMultipleObjects

在我的一个项目中,我创build了多个auto reset events和两个线程,在继续运行之前,线程使用WaitForMultipleObjects等待某些事件,如:

 HANDLE hTerminateEvent = CreateEvent(...); // auto reset HANDLE hStateChangedEvent = CreateEvent(...); // auto reset void thread1Func() { HANDLE handles[2] = { hTerminateEvent, hStateChangedEvent }; WaitForMultipleObjects(2, handles, FALSE/*bWaitAll*/, INFINITE); ... } void thread2Func() { HANDLE handles[2] = { hTerminateEvent, hStateChangedEvent }; WaitForMultipleObjects(2, handles, FALSE/*bWaitAll*/, INFINITE); ... } 

我以前认为,一旦hTerminateEvent被选中,两个线程都会被唤醒,但是对于自动复位事件来说,看起来并不是这样,唤醒是随机的,在唤醒之后,它将hTerminateEvent重置为无信号。

我的问题是如何解决这个问题:通过使用手动重置事件? 还是存在任何devise来解决这个问题? 谢谢!

如果您希望两个线程都对hTerminateEvent作出反应,那么它必须设置为手动重置。 大概你用它作为告诉多个线程终止自己的信号,所以把它设置为自动复位是没有意义的。 和hStateChangedEvent

如果你阅读了CreateEvent()文档,它说:

bManualReset [in]

如果此参数为TRUE,则该函数将创建一个手动重置事件对象,该对象需要使用ResetEvent函数将事件状态设置为非信号。 如果此参数为FALSE,则该函数会创建一个自动重置事件对象,并且在释放一个等待线程后系统会自动将事件状态重置为非信号

手动重置事件对象的状态发出信号时, 它将保持发送状态,直到ResetEvent函数将其显式重置为非信号。 可以释放任何数量的等待线程,或者随后为指定的事件对象开始等待操作的线程,同时可以释放对象的状态

当一个自动重置事件对象的状态发出信号时, 它将保持有信号,直到一个等待线程被释放; 系统会自动将状态重置为非信号 。 如果没有线程正在等待,则事件对象的状态保持发送状态。

所以当使用自动重置事件时,不能同时唤醒正在等待的多个线程。

您可以使用信号量而不是事件,并使用ReleaseSemaphore()并传入等于线程数的计数。