PreviousNext

Condition Variables

A condition variable allows a thread to block its own execution until some shared data reaches a particular state. Cooperating threads check the shared data and wait on the condition variable. For example, one thread in a program produces work-to-do packets and another thread consumes these packets (does the work). If the work queue is empty when the consumer thread checks it, that thread waits on a work-to-do condition variable. When the producer thread puts a packet on the queue, it signals the work-to-do condition variable.

A condition variable is used to wait for a shared resource to assume some specific state (a predicate). A mutex, on the other hand, is used to reserve some shared resource while the resource is being manipulated. For example, a thread A may need to wait for a thread B to finish a task X before thread A proceeds to execute a task Y. Thread B can tell thread A that it has finished task X by using a variable they both have access to, a condition variable. When thread A is ready to execute task Y, it looks at the condition variable to see if thread B is finished (see the following figure).


Thread A Waits on Condition Ready, Then Wakes Up and Proceeds

First, thread A locks the mutex named mutex_ready that is associated with the condition variable. Then it reads the predicate associated with the condition variable named ready. If the predicate indicates that thread B has finished task X, then thread A can unlock the mutex and proceed with task Y. If the condition variable predicate indicated that thread B has not yet finished task X, however, then thread A waits for the condition variable to change. Thread A calls the wait primitive. Waiting on the condition variable automatically unlocks the mutex, allowing thread B to lock the mutex when it has finished task X (see the following figure).


Thread B Signals Condition Ready

Thread B updates the predicate named ready associated with the condition variable to the state thread A is waiting for. It also executes a signal on the condition variable while holding the mutex mutex_ready.


Thread A Wakes Up and Proceeds

Thread A wakes up, verifies that the condition variable is in the correct state, and proceeds to execute task Y (see the figure above).

Note that, although the condition variable is used for explicit communications among threads, the communications are anonymous. Thread B does not necessarily know that thread A is waiting on the condition variable that thread B signals. And thread A does not know that it was thread B that woke it up from its wait on the condition variable.

Use the pthread_cond_init( ) routine to create a condition variable. To create condition variables as part of the program's one-time initialization code, see One-Time Initialization Routines.

Use the pthread_cond_wait( ) routine to cause a thread to wait until the condition is signaled or broadcast. This routine specifies a condition variable and a mutex that you have locked. (If you have not locked the mutex, the results of pthread_cond_wait( ) are unpredictable.) This routine unlocks the mutex and causes the calling thread to wait on the condition variable until another thread calls one of the following routines:

· The pthread_cond_signal( ) routine to wake one thread that is waiting on the condition variable

· The pthread_cond_broadcast( ) routine to wake all threads that are waiting on a condition variable

If you want to limit the time that a thread waits for a condition to be signaled or broadcast, use the pthread_cond_timedwait( ) routine. This routine specifies the condition variable, mutex, and absolute time at which the wait should expire if the condition variable is not signaled or broadcast.

You can delete a condition variable and reclaim its storage by calling the pthread_cond_destroy( ) routine. Use this routine only after the condition variable is no longer needed by any thread. Condition variables are automatically deleted when the program terminates.