|
|
Condition variables are a general mechanism by which one thread can delay its execution until some ``condition'' is true and another thread can announce when some condition is true.
The condition variable (of type cond_t) is part of the mechanism by which this synchronization occurs but that variable is not the ``condition'' itself. This ``condition'' is a somewhat abstract concept (as is ``resource'') that is represented by other code in the program. Some hypothetical examples of conditions are:
One distinguishing feature of the conditional variable mechanism is that two different types of data structures are employed, not just one. A mutual exclusion lock (type mutex_t) must be used in concert with the condition variable (type cond_t) itself. By convention, a thread that evaluates or modifies or acts on the ``condition'' must acquire the associated mutex lock beforehand and release that lock afterward.
The following pseudo-code shows the protocol for a thread that is making some ``condition'' true and announcing the change.
mutex_lock(&mutex); make condition true; cond_signal(&cond); \(lh awaken thread (if any) waiting for condition mutex_unlock(&mutex);
When the thread announces the change of the condition (to being true), it has a choice of awakening either a single thread waiting for that condition or all threads waiting for that condition. The syntax is:
int cond_signal(cond_t *cond); awaken one thread int cond_broadcast(cond_t *cond); awaken all threadsIn either case, there is no problem if there happen to be no waiting threads at the time of announcement.
A thread wanting to delay itself until the ``condition'' is true must first acquire the associated mutex before evaluating the condition. If the condition is true, there is no need for delay and the thread can proceed; otherwise, the thread must call cond_wait(S) to wait for the condition to become true. The following pseudo-code illustrates the programming idiom.
mutex_lock(&mutex) while(condition is false) cond_wait(&cond, &mutex); act on the condition; possibly invalidate it mutex_unlock(&mutex);
The mutex and condition variable used here must be the same data structures as those used in the places where the ``condition'' is made true.
If the ``condition'' is false, cond_wait will:
If the mutex remained locked (and the stated conventions were obeyed) no thread could enter the critical section to make the condition true.
If this were not done, the thread could neither validly re-evaluate the condition (part of the while loop), nor validly act on the condition.
The semantics of condition variables require that a waiting thread re-test the condition on any return from cond_wait(S) or cond_timedwait(S).
Other features of condition variables are: