This article by Anthony Williams is particularly detailed.
Spurious wakes cannot be predicted:
they are essentially random from the
user's point of view. However, they
commonly occur when the thread library
cannot reliably ensure that a waiting
thread will not miss a notification.
Since a missed notification would
render the condition variable useless,
the thread library wakes the thread
from its wait rather than take the
risk.
He also points out that you shouldn't use the timed_wait
overloads that take a duration, and you should generally use the versions that take a predicate
That's the beginner's bug, and one
that's easily overcome with a simple
rule: always check your predicate in a
loop when waiting with a condition
variable. The more insidious bug comes
from timed_wait().
This article by Vladimir Prus is also interesting.
But why do we need the while loop,
can't we write:
if (!something_happened)
c.wait(m);
We can't. And the killer reason is that 'wait' can
return without any 'notify' call.
That's called spurious wakeup and is
explicitly allowed by POSIX.
Essentially, return from 'wait' only
indicates that the shared data might
have changed, so that data must be
evaluated again.
Okay, so why this is not fixed yet?
The first reason is that nobody wants
to fix it. Wrapping call to 'wait' in
a loop is very desired for several
other reasons. But those reasons
require explanation, while spurious
wakeup is a hammer that can be applied
to any first year student without
fail.