Condvars: condition variables
A condition variable, or condvar, is used to block a thread within a critical section until some condition is satisfied. The condition can be arbitrarily complex and is independent of the condvar. However, the condvar must always be used with a mutex lock in order to implement a monitor.
A condvar supports three operations:
- wait (pthread_cond_wait())
- signal (pthread_cond_signal())
- broadcast (pthread_cond_broadcast())
pthread_mutex_lock( &m );
. . .
while (!arbitrary_condition) {
pthread_cond_wait( &cv, &m );
}
. . .
pthread_mutex_unlock( &m );
In this code sample, the mutex is acquired before the condition is tested. This ensures that only this thread has access to the arbitrary condition being examined. While the condition is true, the code sample will block on the wait call until some other thread performs a signal or broadcast on the condvar.
The while
loop is required for two reasons. First
of all, POSIX cannot guarantee that false wakeups will not
occur (e.g., multiprocessor systems). Second, when another
thread has modified the condition, we need to
retest to ensure that the modification matches our criteria.
The associated mutex is unlocked atomically by
pthread_cond_wait()
when the waiting thread is blocked to allow another thread to enter the critical section.
A thread that performs a signal will unblock the highest-priority thread queued on the condvar, while a broadcast will unblock all threads queued on the condvar. The associated mutex is locked atomically by the highest-priority unblocked thread; the thread must then unlock the mutex after proceeding through the critical section.
A version of the condvar wait operation allows a timeout to be specified (pthread_cond_timedwait()). The waiting thread can then be unblocked when the timeout expires.