How does condition_variable :: wait_for () handle false awakenings?

Fake wakup is allowed on various platforms. To counter this, we write the cyclization mechanism below:

while(ContinueWaiting()) cv.wait(lock); // cv is a `std::conditional_variable` object 

The same is clear for conditional_variable::wait_until() .
But look at an example below:

 const auto duration = Returns_10_seconds(); while(!Predicate()) cv.wait_for(lock, duration); 

Imagine that a false awakening occurred after 1 second. Timeout not yet reached.
Wait another 10 seconds? This will lead to an endless loop, which I am sure should not happen. From the source code, inside wait_for() calls wait_until() .

I want to understand how wait_for() deals with false awakenings?

+5
source share
3 answers

I want to understand how wait_for() deals with false awakenings?

This is not true.

This function is usually used in situations where you wake up falsely, you still want to do some other work. And if you do not wake up falsely, you want to make the “false” wake up by the time you pass duration . This means that it is not usually used in a loop, as you show, precisely for the reasons you specify. That is, timeouts and false awakenings are handled the same way.

Now you may be wondering what the predicate version does, since it involves a loop?

 template <class Rep, class Period, class Predicate> bool wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred); 

It is indicated that it has the same effects as:

 return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred)); 

The wait_until variation distinguishes between false wakefulness and timeouts. He does it like this:

 while (!pred()) if (wait_until(lock, abs_time) == cv_status::timeout) return pred(); return true; 
+4
source

Here, what the standard has to say about side awakenings:

30.5 State variables [thread.condition]

Variable conditions provide synchronization primitives that are used to block a thread until they are notified by some other one so that a condition is met or until the system time is reached.

...

10 Note. It is the responsibility of users to ensure that waiting threads do not erroneously assume that the thread is terminated if they experience side awakenings.

From the wording, it seems pretty clear that the responsibility for handling false awakenings lies with the user.

+2
source

 
      const auto duration = Returns_10_seconds (); 
      while (cv.wait_for (lock, duration) == std :: cv_status :: timeout); 
 

This is definitely the wrong thing, and therefore it makes no sense to discuss how to fix it for the case of false awakenings, as it is violated even for ordinary awakenings, since the waiting condition is not reviewed after returning from the wait. Strike>

 const auto duration = Returns_10_seconds(); while(!Predicate()) cv.wait_for(lock, duration); 

Even after editing, the answer remains unchanged: you cannot handle the “false awakenings” because you cannot really explain the reason for the awakening - it is quite possible that it will be completely legal awakening due to a call before condition_variable::notifyXXX before the timeout expires.

First, note that you cannot distinguish between waking up caused by calling condition_variable::notifyXXX and waking up caused, for example, by a POSIX signal [1]. Secondly, even if the POSIX signals are not disturbing, the waiting thread should still review the condition, since it is possible for the condition to change between the time when the status signaling is signaled and the waiting thread returns from the waiting condition.

What you really need to do is handle it in a special way, not waking up before a timeout, but waking up due to a timeout. And it completely depends on the reasons for having a timeout in the first place, i.e. From the specifics of the application area / problems.

[1] if the wait on the condition variable is interrupted by a signal, after the thread handler is executed, the thread is allowed to either resume the wait or return

+1
source

All Articles