Alex Rivera | Logout

Why is a while loop needed around pthread wait conditions?

Asked 2009-07-16T09:17:09.853
51

I'm learning pthread and wait conditions. As far as I can tell a typical waiting thread is like this:

pthread_mutex_lock(&m);
while(!condition)
     pthread_cond_wait(&cond, &m);
// Thread stuff here
pthread_mutex_unlock(&m);

What I can't understand is why the line while(!condition) is necessary even if I use pthread_cond_signal() to wake up the thread.

I can understand that if I use pthread_cond_broadcast() I need to test condition, because I wake up all waiting threads and one of them can make the condition false again before unlocking the mutex (and thus transferring execution to another waked up thread which should not execute at that point). But if I use pthread_cond_signal() I wake up just one thread so the condition must be true. So the code could look like this:

pthread_mutex_lock(&m);
pthread_cond_wait(&cond, &m);
// Thread stuff here
pthread_mutex_unlock(&m);

I read something about spurious signals that may happen. Is this (and only this) the reason? Why should I have spurious singnals? Or there is something else I don't get?

I assume the signal code is like this:

pthread_mutex_lock(&m);
condition = true;
pthread_cond_signal(&cond); // Should wake up *one* thread
pthread_mutex_unlock(&m);
Edit
Report

1 Answer

17

Suppose you don't check the condition. Then usually you can't avoid the following bad thing happening (at least, you can't avoid it in one line of code):

 Sender                             Receiver
locks mutex
sets condition
signals condvar, but nothing 
  is waiting so has no effect
releases mutex
                                    locks mutex
                                    waits. Forever.

Of course your second code example could avoid this by doing:

pthread_mutex_lock(&m);
if (!condition) pthread_cond_wait(&cond, &m);
// Thread stuff here
pthread_mutex_unlock(&m);

Then it would certainly be the case that if there is only ever at most one receiver, and if cond_signal were the only thing that could wake it up, then it would only ever wake up when the condition was set and hence would not need a loop. nos covers why the second "if" isn't true.

answered 2009-07-16T10:27:30.273

Your Answer