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);