Variables that can be used to wait for a condition to become true and to signal another thread when the condition has been satisfied.
Declaration and initialization:
pthread_cond_t condition; pthread_cond_init(&condition, NULL);
They are always used in conjunction with a mutex variable. A thread can wait for something to happen by calling pthread_cond_wait, and it must explicitly lock the mutex before and unlock it afterwards
Using Condition Variables
pthread_mutex_t mutex; pthread_mutex_lock(&mutex); pthread_cond_wait(&condition, &mutex); pthread_unlock(&mutex);
The condition is actually satisfied by another thread that can unblock the first one by calling the pthread_cond_signal:
pthread_mutex_lock(&mutex); pthread_cond_signal(&condition); pthread_unlock(&mutex);
If there is more than one thread waiting, the pthread_cond_wait must be replaced by pthread_cond_broadcast.
Condition Wait
pthread_cond_wait(condition, mutex) { cond.waiting++; while (true) { if (condition.signal>0) { cond.waiting--; cond.signal--; unlock(&mutex); lock(&mutex); return; } else { unlock(&mutex); wait(); lock(&mutex); } } }
Condition Signal and Broadcast
pthread_cond_signal(condition) { if (condition.waiting>condition.signal) condition.signal += 1; } pthread_cond_broadcast(condition) { if (condition.waiting>signal) condition.signal = condition.waiting; }
Conditional Critical Section
Thread() { pthread_mutex_lock(&mutex); while(!test_condition(...)) pthread_cond_wait(&condvar, &mutex); do_stuff(...); pthread_cond_signal(&condvar); pthread_mutex_unlock(&mutex); }
Example: the Barrier
void Barrier(int thread_nr) { static int count = 0; pthread_mutex_lock(&mutex); count++; if (count == thread_nr) { pthread_cond_broadcast(&cond); count = 0; } else pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); }
Barriers
A new feature in the 1003.1j-2000 standard.
pthread_barrier_t barrier; pthread_barrier_init(&barrier, NULL, nr_threads); pthread_barrier_wait(&barrier);