If std::condition_variable
can be signaled due to the spurious wakeups (and we can't be sure that the condition we need is really satisfied), why do C++ Standard Library provide the overloads of wait()
method without a predicate? What are the scenarios when such behaviour can be used?

- 1,779
- 13
- 33
-
1I can only guess that because traditionally posix and windows API provided condition variable without a predicate the comitee wanted to preserve the original use/API of them but with a standard , portable form. other than that, I see no reason using cv's without predicate – David Haim Jan 26 '16 at 11:58
-
Historically, it was accepted that system calls, eg. those for inter-thread comms, worked correctly every time they were called. – Martin James Jan 26 '16 at 12:05
-
1@MartinJames The implementation can't prevent spurious wakeups. It's not a matter of the system call working correctly, it's the inherent race between a thread that is deciding whether to block and a thread that is unblocked but not yet running. (For example, two messages go on a queue. We wake two threads. If the first thread processes both messages, the second thread will see a spurious wakeup.) – David Schwartz Jan 26 '16 at 12:07
3 Answers
Assume a complex condition: A || B
. When any part of the condition is true, appropriate action, actionA
or actionB
, should be perfomed.
Using predicate version, the code could be following:
cond.wait(lock, []{return (A || B);});
if(A) {
actionA();
}
else {
actionB();
}
But the code may be faster if use non-predicate wait:
while(true)
{
if(A) {
actionA();
break;
}
else if(B) {
actionB();
break;
}
cond.wait(lock);
}
Note, that unlike to the first variant, now every condition part is evaluated once.
There are more complex cases, when a condition cannot be written in a single expression.

- 60,011
- 17
- 110
- 153
-
If you imagine complex code where different things inside the predicate test result in different flows of control, you could wind up with either an overly-complex predicate or an ugly structure just to get information out of the predicate and restore the right point in the flow of control. – David Schwartz Jan 26 '16 at 12:03
-
@DavidSchwartz: It depends. The simplest example of two-part condition with different reactions is reading a queue which may be ended(EOF). As for `over-complex` and `ugly structure` - multithreading by itself is a complex thing. Sometimes it is desireable to sacrifice program readability for simplify multithreaded aspects. – Tsyvarev Jan 26 '16 at 12:16
why do C++ Standard Library provide the overloads of wait() method without a predicate
The predicate version of wait
is equivalent to:
while (!pred()) {
wait(lock);
}
If you need more complex code to be executed before and/or after waiting you may like to use wait
without the predicate.

- 131,725
- 17
- 180
- 271
I guess there are cases where spurious wakeups are not the end of the world.
E.g., consider a producer-consumer batch processing system, where some thread should wake up when there are, say, at least 100 messages in a queue, and process them.
Given spurious wakeups, it might reap fewer than 100 messages, occasionally. The difference might not warrant the overhead and extra complexity of the condition function.

- 74,578
- 11
- 141
- 185
-
1This is an example of a case where you'd either have to put the actual code to reap the messages in the predicate to avoid the extra overhead or use a dummy predicate that tests nothing. Either of those solutions would be ugly. – David Schwartz Jan 26 '16 at 12:05