Namespaces
Variants
Actions

Talk:cpp/thread/condition variable/wait for

From cppreference.com

There are some implementations which can not guarantee that when you return from the wait with a timeout, that the variable is not signaled. This is a known race, it's even part of the pthread standard doc with the relevant section below: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html

Quote:

   Condition Wait Semantics
   It is important to note that when pthread_cond_wait() and pthread_cond_timedwait()
   return without error, the associated predicate may still be false. Similarly, when 
   pthread_cond_timedwait() returns with the timeout error, the associated predicate may be
   true due to an unavoidable race between the expiration of the timeout and the predicate
   state change.

   The application needs to recheck the predicate on any return because it cannot be sure
   there is another thread waiting on the thread to handle the signal, and if there is not
   then the signal is lost. The burden is on the application to check the predicate.

It seems like it would be advantageous to mention this possible issue in the reference, however I'm not sure if it is appropriate to do so on the page it self, as it's really implementation dependent.

Bgianfo (talk) 16:55, 19 January 2016 (PST)

It looks obvious to me, but I suppose it deserves a line under Notes. --Cubbi (talk)

Contents

[edit] Race Condition in Example Code

[edit] Race Condition in Example Code

Even atomic variables should be protected by mutex to avoid race condition. Also `cv_m` mutex probably should be renamed to `i_m` to clarify that it is "i shared state mutex", not "conditional variable mutex"

alex3d 46.39.238.140 22:02, 14 October 2016 (PDT)

can you explain in more detail what race condition you're seeing? Concurrent access to an atomic variable without synchronization is not a race, by definition. One of the waiting threads in the example may not be scheduled in time for the notification, so the output may not be deterministic, is that what you're referring to? --Cubbi (talk) 04:25, 15 October 2016 (PDT)


I mean that variable change notification via cv can be lost when state variable/flag changed without mutex even if it is atomic variable (isn't it a race condition?). In general case it can be dangerous especially when using wait without timeout.
Counterexample:
Thread 1:
atomic_flag = true;
cv.notify_one();
Thread 2:
unique_lock lock(mutex);
while(!atomic_flag)
cv.wait()
Execution:
2: unique_lock lock(mutex);
2: while(!atomic_flag) // still false...
1: atomic_flag = true;
1: cv.notify_one(); // no one to notify
2: cv.wait()
(See also http://stackoverflow.com/questions/32978066 used it main CV article)
alex3d 77.72.80.1 01:42, 17 October 2016 (PDT)
ah, yes, indeed, {{c|i|| is assigned to in signals() while it is not under cv's mutex, contradicting cpp/thread/condition_variable's contract. Good catch. --Cubbi (talk) 06:06, 17 October 2016 (PDT)

[edit] Lambda uses not captured variable

The predicate lambda in the cv.wait_for( call

    if(cv.wait_for(lk, std::chrono::milliseconds(idx*100), [](){return i == 1;})) 

seems to use `i` without capturing it in any way. What do I miss if that makes sense?

73.211.239.3 16:39, 3 December 2016 (PST)

that is a global variable in that example, much like std::cout. Global variables can be used anywhere. --Cubbi (talk) 08:25, 4 December 2016 (PST)

[edit] GCC Monotonicity Bug

I feel like this page should mention the rather severe GCC bug:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861

This page implies wait_for can be used for monotonic sleeps, but in fact it cannot under many (most?) versions of GCC. This burned me pretty bad.

139.85.193.105 08:26, 13 January 2020 (PST) Bryan

[edit] Example not showing wait_for()?

It looks like the example is showing the use of `wait()` but not the `wait_for()` function which this page is about. I think the example needs to be updated.