4

I can't find any evidence online of pthread_cond_wait being strange on Mac OS X, but it seems to be failing the simplest test for me.

The function

int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t * ); 

is supposed to unlock the mutex argument #2 and then wait for a signal to be sent on the condition argument #1. I wrote a simple program to test this, and also test for spurious wakeups:

#include <stdio.h> #include <pthread.h> pthread_t spin_thread; pthread_mutex_t spin_mutex; pthread_cond_t spin_cond; int actual = 0; void *condspin( void *v ) { int expected = 0; for ( ;; ) { if ( actual != expected ) printf( "unexpected %d\n", actual ); else printf( "expected %d\n", actual ); pthread_mutex_lock( &spin_mutex ); printf( "locked\n" ); expected = actual + 1; pthread_cond_wait( &spin_cond, &spin_mutex ); } return NULL; } int main( int argc, char ** argv ) { pthread_mutex_init( &spin_mutex, NULL ); pthread_cond_init( &spin_cond, NULL ); pthread_create( &spin_thread, NULL, &condspin, NULL ); for ( ;; ) { getchar(); pthread_cond_signal( &spin_cond ); printf( "signaled\n" ); ++ actual; } return 0; } 

But it only acquires the lock once. The main thread doesn't even try to acquire the lock just to keep things simple.

Shadow:~ dkrauss$ cc condwait.c -o condwait Shadow:~ dkrauss$ ./condwait expected 0 locked signaled expected 1 signaled signaled 

If I add a pthread_mutex_unlock after the pthread_cond_wait, it behaves as expected. (Or as well as you'd expect with only half a locking mechanism.) So, what gives?

1 Answer 1

8

pthread_cond_wait re-acquires the mutex when it is awoken. The standard pattern for using pthreads mutexes is:

pthread_mutex_lock(&mutex); // init work... while (!some_condition) pthread_cond_wait(&cond, &mutex); // finishing work... pthread_mutex_unlock(&mutex); 

This behavior is described in the SUS documentation for pthread_cond_wait as:

Upon successful return, the mutex has been locked and is owned by the calling thread. 
Sign up to request clarification or add additional context in comments.

3 Comments

Aha! Makes perfect sense! Now why don't any of the docs I read (and I read a few) say so???
it is documented in the SUS spec (citation added), and also in the linuxthreads manpage for pthread_cond_wait. I don't know about mac os x, but it should document this as well...
OS X has almost no documentation. It says this and only this: "The pthread_cond_wait() function atomically unlocks the mutex argument and waits on the cond argument." I did actually read the reference you provided but I was confused by its use of the passive voice. "The mutex has been locked" is a confusing way of saying "the function locks the mutex," especially in an interface where many requirements fall upon the user.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.