Reputation: 1168
In one of my projects, I created multiple auto reset events
and two threads, the threads use WaitForMultipleObjects
to wait on some events before continuing run, like:
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);
...
}
I previously thought that once hTerminateEvent
is singled, both threads will be waken up, but seems that is not true for auto reset events, which one gets waken up is random, and after one wakes up, it reset the hTerminateEvent
to un-signaled.
My question is how to resolve this: by using manual reset event? or does there exist any design to solve this problem? thanks!
Upvotes: 1
Views: 2504
Reputation: 595422
If you want both threads to react to hTerminateEvent
then it must be set to manual reset. Presumably you are using it as a signal to tell multiple threads to terminate themselves, so it does not make sense to set it as auto reset anyway. Same with hStateChangedEvent
.
If you read the CreateEvent()
documentation, it says:
bManualReset [in]
If this parameter is TRUE, the function creates a manual-reset event object, which requires the use of the ResetEvent function to set the event state to nonsignaled. If this parameter is FALSE, the function creates an auto-reset event object, and system automatically resets the event state to nonsignaled after a single waiting thread has been released.
...
When the state of a manual-reset event object is signaled, it remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object, can be released while the object's state is signaled.
When the state of an auto-reset event object is signaled, it remains signaled until a single waiting thread is released; the system then automatically resets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.
So when using an auto-reset event, you cannot wake up multiple threads that are waiting on it at the same time.
Upvotes: 3
Reputation: 1237
You can use a semaphore instead of event, and use ReleaseSemaphore() and pass in the count that is equal to the number of threads.
Upvotes: 1