简体   繁体   中英

Does std::condition_variable_any have awkward semantics?

Using POSIX condition variable you would write something like this:

while (!_doneWaiting) {
    wait(lock);
}

At first when I saw the new C++11 style, I was excited:

unique_lock<recursive_mutex> g(_consumerCondLock);
_consumerCond.wait( g, [this]() {
    return _doneWaiting;
} );

But an annoyance has occured to me: Is the predicate lambda above guaranteed to run once before any waiting occurs?

Is the predicate lambda above guaranteed to run once before any waiting occurs?

The condition you wait for must be checked:

  1. Before waiting on the condition variable.
  2. After waiting on the condition variable because of spurious wakeups .

This is why the canonical form of waiting on a condition variable is a while loop:

// lock the mutex
while(!condition)
    // wait on the condition variable

Which is what std::condition_variable::wait does for you.


Note, that most of the time you want std::condition_variable instead of std::condition_variable_any . That latter maintains its own mutex and is more expensive in terms of memory and run-time.

Yes, it has to run before waiting. If we look at the reference( which is consistent with the draft C++ standard section 30.5.2 Class condition_variable_any ) for std::condition_variable_any::wait it says that:

template< class Lock, class Predicate >
void wait( Lock& lock, Predicate pred );

is equivalent to:

while (!pred()) {
  wait(lock);
}

and says:

This overload may be used to ignore spurious awakenings while waiting for a specific condition to become true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM