PreviousNext

Thread Communication and Synchronization

Threads communicate through shared variables - one thread sets a variable that another thread later reads. However, if multiple threads are accessing the same variable, incorrect results can occur due to scheduling of threads and race conditions. To resolve this problem, access to shared variables must be synchronized. DCE Threads provides three facilities for synchronizing threads within a process:

· Mutual exclusion objects (mutexes)

· Condition variables

· The join routine

The mutex object is used to synchronize access to a given resource, such as a shared variable, by multiple threads. Mutexes ensure that only one thread accesses the resource associated with the mutex at a time - thus the mutual exclusion or mutex name.

The mutex works as follows. One mutex object is associated with each shared resource; for example, a shared variable. Before reading or writing the variable, a thread attempts to lock the variable's mutex. If it succeeds in locking the mutex, the thread proceeds to access the variable, and then it unlocks the mutex.

If a second thread tries to access the object while the first thread is accessing it (the condition that can cause indeterminate results if the shared variable is not protected), the second thread is blocked when it tries to lock the mutex. When the first thread finishes with the variable and unlocks the mutex, the second thread is unblocked and gains the lock for the mutex. It can then proceed to access the shared variable.

The mutex is a facility by which threads can ensure that their access to shared resources is synchronized. The threads may or may not be communicating through the shared data. The second method of thread synchronization, the condition variable, is used for explicit communications among threads. This is done through the use of a shared resource - the condition variable - and as a result requires the use of a mutex.

For example, using a condition variable, Thread A can wait for Thread B to accomplish some task. To do this, Thread A waits on the condition variable until Thread B signals the condition variable, indicating that the particular task has been accomplished.

Note that although the condition variable is used for explicit communications among threads, the communications are anonymous. For example, 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.

There is another synchronization method that is not anonymous - the join routine. This allows a thread to wait for another, specific thread to complete its execution. When the second thread has finished, the first thread unblocks and continues its execution. Unlike mutexes and condition variables, the join routine is not associated with any particular shared data.