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?
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.
over-complex
and ugly structure
- multithreading by itself is a complex thing. Sometimes it is desireable to sacrifice program readability for simplify multithreaded aspects. –
Dripdry 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.
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.
© 2022 - 2024 — McMap. All rights reserved.