4

The MSDN page for SleepConditionVariableCS states that

Condition variables are subject to spurious wakeups (those not associated with an explicit wake) and stolen wakeups (another thread manages to run before the woken thread). Therefore, you should recheck a predicate (typically in a while loop) after a sleep operation returns.

As a result the conditional wait has to be enclosed in a while loop i.e.

while (check_predicate())
{
    SleepConditionVariableCS(...)
}

If I were to use events instead of Conditional Variables can I do away with the while loop while waiting (WaitForSingleObject) for the event to be signaled?

work.bin
  • 1,078
  • 7
  • 29

1 Answers1

8

For WaitForSingleObject(), there are no spurious wakeups, so you can eliminate the loop.

If you use WaitForMultipleObjectsEx() with bAlertable=TRUE, MsgWaitForMultipleObjects() with a wake mask, or MsgWaitForMultipleObjectsEx() with bAlertable=TRUE or a wake mask, then the wait can end on other conditions before the event is actually signaled.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks. Any idea why Conditional Variables are susceptible to spurious wakeups while Events don't have that problem? – work.bin Aug 04 '16 at 02:59
  • 1
    @work.bin: it is just the way condition variables work in general. It is not limited to Microsoft's implementation, either. [pthreads suffers from it](http://stackoverflow.com/questions/8594591/), [so does STL](http://en.cppreference.com/w/cpp/thread/condition_variable), and [boost, too](http://www.boost.org/doc/libs/1_58_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref). As to *WHY*, condition variables are *user-mode* objects, whereas events are *kernel* objects. The kernel does not have spurious wakes, but user-mode can, depending on thread scheduling and such. – Remy Lebeau Aug 04 '16 at 03:19