When can std::condition_variable be used without a predicate?

2.4k views Asked by At

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?

3

There are 3 answers

2
Tsyvarev On

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.

1
Ami Tavory On

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.

0
Maxim Egorushkin On

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.