None of the wait functions will ever return without the lock being held--not on normal wakeups,
not on timeouts, not on spurious wakeups, not even on cancellation or interruption. It is possible
that right after waking up, a thread must go back to sleep because the lock is held by another
Other Synchronization Variables
The join functions are similar to synchronization variables in that they allow you to synchronize
threads on the event of another thread exiting. You almost never actually care when a thread exits,
and almost everything you do with join, you can do with the other synchronization variables (see
A barrier allows a set of threads to sync up at some point in their code. It is initialized to the
number of threads using it, then it blocks all the threads calling it until it reaches zero, at which
point it unblocks them all. The idea is that you can now arrange for a set of threads to stop when
they get to some predefined point in their computation and wait for all the others to catch up. If
you have eight threads, you initialize the barrier to eight. Then, as each thread reaches that point, it
decrements the barrier and then goes to sleep. When the last thread arrives, it decrements the
barrier to zero, and they all unblock and proceed (Figure 7-5).
Figure 7-5. Barriers
Barriers are not part of any of the libraries, but they are easily implemented. They are also
implemented in our extensions package and are part of the proposed extensions to POSIX.
A single barrier is similar to a barrier, except that one (possibly more) thread will be waiting for
the others (Figure 7-6). This is the synchronization technique we use in our programs to count
threads as they exit (instead of joining them all). Basically, each thread increments the single
barrier as it completes its work, while a single thread waits for them. When the last thread posts,
the sleeper is awakened.
Figure 7-6. Single Barriers
Search WWH :