People seem to be dealing with spurious wakeups exclusively, but there is a more fundamental reason why a while
or an if
is to be used in monitor procedures.
We would have to choose one or the other even if there were no spurious wakeups because monitor implementations may choose from a number of different signaling disciplines.
The following paper describes these
John H. Howard. 1976. Signaling in monitors. In Proceedings of the 2nd international conference on Software engineering (ICSE '76). IEEE Computer Society Press, Los Alamitos, CA, USA, 47-52.
The point is that a monitor can be used by at most one process at a time, and there is a conflict when a waiting process is being woken up (signaled) by another process from inside the monitor. The problem is: which process may continue executing inside the monitor?
There are a number of different disciplines. The one originally proposed is the so called signal and wait, where the signaled process continues immediately (the signaler has to wait). Using this discipline the
if ( predicate) {
cond_var.wait( &lock);
}
form can be used because the predicate must be true after waiting (provided it is true at the time of signaling)
Another discipline is signal and continue, where the signaling process continues, the signaled is put into an entry queue of the monitor. Using this discipline necessitates the use of the
while ( predicate) {
cond_var.wait( &lock);
}
form because predicate can be invalidated by the time the signaled process gets a chance to execute, so it has to retest the condition.