Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::condition_variable::wait with predicate

In the documentation for std::condition_variable, there is an overload of wait() taking as argument a predicate function. The function will wait until the first wake_up at which the predicate function is true.

In the documentation

It is stated that this is equivalent to:

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

But also:

This overload may be used to ignore spurious awakenings while waiting for a specific condition to become true. Note that before enter to this method lock must be acquired, after wait(lock) exits it is also reacquired, i.e. lock can be used as a guard to pred() access.

I'm not sure to understand, are these strictrly equivalent (in which case I prefer the plain while loop which is easier to read than the overload with a lambda in my case), or is the overload (possibly implementation depending) more efficient?

Could an implementation evaluate the predicate in the notifying thread before awakening the waiting thread, in order to avoid awakening when the test condition is false? c++ thread guru needed here...

Thanks

like image 864
galinette Avatar asked Nov 13 '15 12:11

galinette


1 Answers

Implementations can try to make it better than the loop from performance standpoint, but I doubt it is possible. It is very straitghtforward, and you can check your implementation to see how it is done. This is what gcc 4.9.2 does here:

template<typename _Predicate>
  void
  wait(unique_lock<mutex>& __lock, _Predicate __p)
  {
      while (!__p())
        wait(__lock);
  }

As you can see, it is exactly the same, and I doubt something else can be done here. As for readability, it is more readable than loop. However, you probably misunderstand the reason for this. This loop is simply supposed to check that the real variable guaraded by condition did indeed change to the value you expect it to be - as it might have not. The usual code snipped looks like this:

cond_var.wait(lock, []() { return bool_var == true; })
like image 116
SergeyA Avatar answered Nov 14 '22 07:11

SergeyA