Conditions


Detailed Description

Conditions are syncrhonization objects that a thread can wait for.

A condition is bound with a mutex (see Thread::Mutex) and with a predicate. A predicate is a set of tests that may evalute to true or false at a given time; the goal of a condition variable is to make a user thread to wait for a predicate to become true before to proceed. When a different thread changes the data so that the predicate may become true, it "signals" the condition; this wakes the waiting threads and makes them to check again for the predicate being now true. If it is so, the waiting threads will proceed and complete its opeartions.

A program using a condition must check a predicate whose status depends on operations done by other threads; hence the need to use a mutex to secure the access to the data that is checked by the predicate. Entering the wait will automatically and atomically unlock the mutex, allowing other threads to lock it and work on the shared data; the mutex is then re-locked on wakeup, so that the waiting thread can safely check the condition and eventually work on the shared data.

The relationship between mutexes and conditions is 1:N, that is, a condition may be related only with a mutex, but a mutex can be used in more than one predicate. A well designed program uses a condition for each predicate to check, although is possible to design applications where a single condition is used to control more than a predicate. However, doing so will result in a waste of context swapping, as when a condition is signaled, some thread whose predicate has data unaltered will be awaken and will do an useless test that will be still false as before. The time used to test the predicate may be trivial, but a useles context switch is a considerable waste of system resources.

Condition wait can be timed. If a thread wishes, it can wait for a condition just for a given time; if the condition is not notified in that time, the thread is awaken and signaled about this timeout; the thread must then act as if the predicate was false and terminate its waiting process.

Waits can also be interrupted by an external event; this is one of the reasons why it is necessary to check if the predicate is true after a wait is terminated; in fact, the thread may return in control after a condition wait even if the condition is not signaled, or if the condition is erroneusly signaled by a thread that is not really making the whole predicate to become true (i.e. the predicate may be a check on two variables, and a thread may signal after having changed just one of them).

A waiting process may also be stopped, if it allows so. When this happens, the mutex used by the condition is relocked, and a cleanup function is called. It is necessary to provide a cleanup code, because there is no way by which the mutex is going to be freed by itself; anyhow, a condition wait usually needs more cleanup than just releasing the owned mutex. Any non-trivial program using conditions will need a cleanup routine on its own, and that cleanup routine will find the mutex locked to be very handy.

Note:
This "condition" defintion mimics the posix threading condition variables. Wefts is based on this concept because its designers found this model flexible, useful, and safe. If the underlying system has posix threading support, then pthread_cond* is used as a low level OS layer, else this behavior is obtained by re-implementing the conditions.
There is an interesting How to use condition variables and mutexes about usage of conditions


Classes

class  Wefts::Condition
 Class implementing a condition variable. More...

class  Wefts::FastCondition
 Fast mutex + condition structure wrapper. More...

class  Wefts::RCondition
 Reentrant mutex + condition structure wrapper. More...


Generated on Tue Oct 5 14:57:01 2004 for Wefts by doxygen 1.3.7