Zhi Wang
Zhi Wang

Reputation: 1168

Use WaitForMultipleObjects on multiple auto reset events

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

Answers (2)

Remy Lebeau
Remy Lebeau

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

SeaStar
SeaStar

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

Related Questions