2

I'm trying to wrap my head around pthread condition variables. I've seen some code examples that use pthread_cond_wait and pthread_cond_signal and all of them look like this:

while (condition)
{
    // Assume that the mutex is locked before the following call
    pthread_cond_wait(&cond, &mutex);
}

Is there a reason for using a while loop on the condition? why not just use a single if statement?

3 Answers3

1

I believe this is because threads may be spuriously woken up before the condition is met. Man, talk about "gotcha's".

From the Open Group documentation:
"Spurious wakeups from the pthread_cond_wait() or pthread_cond_timedwait() functions may occur."

Source:
http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html

Tripnull
  • 11
  • 1
1

Spurious wakeups.

See Why does pthread_cond_wait have spurious wakeups? and also https://en.wikipedia.org/wiki/Spurious_wakeup:

Spurious wakeup describes a complication in the use of condition variables as provided by certain multithreading APIs such as POSIX Threads and the Windows API.

Even after a condition variable appears to have been signaled from a waiting thread's point of view, the condition that was awaited may still be false. One of the reasons for this is a spurious wakeup; that is, a thread might be awoken from its waiting state even though no thread signaled the condition variable. For correctness it is necessary, then, to verify that the condition is indeed true after the thread has finished waiting. Because spurious wakeup can happen repeatedly, this is achieved by waiting inside a loop that terminates when the condition is true ...

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Spurrious wakeups are part of the reason, but not the whole reason. – John Bollinger Dec 21 '16 at 22:12
  • @JohnBollinger Are you referring to the reasons mentioned here: http://stackoverflow.com/a/8594644/4756299 ? – Andrew Henle Dec 21 '16 at 22:13
  • I am asserting that "A thread blocked in pthread_cond_wait returns because of a call to signal or broadcast, however after reacquiring the mutex the underlying predicate is found to no longer be true" (quoted from your SO reference) is not properly classified as a "spurrious wakeup". Your Wikipedia article seems to agree with me on that detail of terminology. – John Bollinger Dec 21 '16 at 22:16
  • @JohnBollinger To me, that seems too much like a distinction without a difference - `pthread_cond_wait()` returned, but the predicate condition is `false`. I don't see how the calling code can discern any difference between that and a "true" spurious wakeup. – Andrew Henle Dec 21 '16 at 22:22
  • The term "spurrious wakeup" is ordinarily used with a specific meaning much narrower than the one you have used. Heck, even the quote in your post uses it that way. If we want to be able to talk about that particular kind of event, then it's important to not dilute the meaning of the term that specifically refers to it. More significantly, the *other* reason for re-checking the condition is much more important in practice, but lumping it in with spurrious wakeups as you have done obscures it. – John Bollinger Dec 21 '16 at 22:30
1

Is there a reason for using a while loop on the condition? why not just use a single if statement?

The idea behind condition variables is to suspend thread execution until a given condition is satisfied. The condition is not built into the variable, however -- it must be provided by the programmer.

If the relevant condition is already satisfied, then there is no need to suspend operation. The key here, however, is that when the thread resumes, the condition might still not be satisfied, either because something changed between the condition variable being signaled and the thread being able to proceed, or because the thread awoke spurriously (this is allowed to happen, though it rarely does). The program therefore checks the condition again upon every wakeup to see whether it must resume waiting.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157