Information Technology Reference
In-Depth Information
when signal() or broadcast() was called, it may no longer be true when
wait() returns. This may seem like a small window of vulnerability, but
we need to design concurrent programs to work with all possible sched-
ules. Otherwise, programs may fail sometimes, but not always, making
debugging very dicult. See the sidebar on Hansen v. Hoare semantics
on page 206 for a discussion of the history behind this property.
Note to programmers. The points above have an important implication for
programmers: wait() must always be called from within a loop.
Because wait() releases the lock and because there is no guarantee of atom-
icity between signal()/broadcast() and the return of a call to wait() , when
a thread returns from wait() , there is no guarantee that the checked-for state
holds. Therefore, a waiting thread must always wait in a loop, rechecking the
state until the desired predicate holds. Thus, the design pattern is
...
while(predicateOnStateVariables(...)){
wait(&lock);
}
...
and not
...
if(predicateOnStateVariables(...)){
wait(&lock);
}
...
There are fundamentally two reasons why condition variables are designed to
impose this requirement: simplifying implementation and improving modularity.
Implementation: As noted above, when a waiting thread is reenabled, it
may not run immediately, other threads may access the shared state before it
runs, and the desired predicate on the shared state may no longer hold when
wait() finally does return.
This definition simplifies the implementation of condition variables without
hurting the complexity of the code that uses them. No special code is needed for
scheduling|we just put a signalled thread onto the scheduler's ready list and
let it run whenever the scheduler chooses it. Similarly, no special code is needed
for acquiring the lock|we just have the thread call Lock::acquire() when
it is rescheduled; just as with any attempt to acquire a lock, it may succeed
immediately, or it have to wait while other threads acquire and release the lock.
Some implementations go even further and warn that a call to wait() may
return even if no thread has called signal() or broadcast(). So, not only is it
possible that the desired predicate on the state is no longer true, it is possible
that the desired predicate on the state was never true. For example, Sun's Java
JDK1.5's interface to condition variables allows for \spurious wakeups":
 
Search WWH ::




Custom Search