在我的一个项目中,我创建了多个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重置为无信号。
我的问题是如何解决这个问题:通过使用手动重置事件?或者有没有什么设计可以解决这个问题?谢谢!
发布于 2012-12-12 10:59:12
如果您希望两个线程都对hTerminateEvent做出反应,则必须将其设置为手动重置。假设您将其用作通知多个线程自行终止的信号,因此将其设置为自动重置是没有意义的。hStateChangedEvent也是如此。
如果您阅读CreateEvent()文档,它会说:
bManualReset in
如果此参数为TRUE,该函数将创建一个手动重置事件对象,该对象需要使用ResetEvent函数将事件状态设置为无信号。如果该参数为FALSE,则函数会创建一个自动重置事件对象,在单个等待线程被释放后,系统会自动将事件状态重置为无信号。
..。
当手动重置事件对象的状态为signaled时,它将保持signaled状态,直到被ResetEvent函数显式重置为nonsignaled为止。当指定事件对象的状态被通知为时,可以释放任意数量的等待线程或随后开始对指定事件对象执行等待操作的线程。
当自动重置事件对象的状态是有信号的时,它将保持有信号状态,直到释放单个等待线程;然后系统自动将状态重置为无信号。如果没有线程在等待,则事件对象的状态保持为有信号状态。
因此,在使用自动重置事件时,不能同时唤醒正在等待该事件的多个线程。
发布于 2012-12-12 10:42:55
您可以使用信号量而不是事件,并使用ReleaseSemaphore()并传入与线程数相等的计数。
https://stackoverflow.com/questions/13831855
复制相似问题