predicate for condition variable
Asked Answered
I

2

7

I am new to multi threading. While writing multi threaded code in C++11 using condition variable , I use the following construct

while(predicate) {
    cond_var.wait(&lock);
}

However, I have been reading Deitel's third edition book on operating systems(chp 6) where the following construct is being used

if(predicate) {
    cond_var.wait(&lock);
}

So, what's the difference? Why isn't the book using while? Isn't spurious call an issue?

Idioblast answered 3/4, 2014 at 10:38 Comment(1)
While concurrency with condition variables is a suitable topic for Computer Science, your question is really more about how the C++ implementation behaves. This is a programming question, more suitable for Stack Overflow, so I am migrating it there.Hardhearted
L
11

Spurious wakeup is always a potential issue. For example, look at the answers here: Do spurious wakeups actually happen?. Perhaps Deitel's code is part of a larger loop that can help them deal with the spurious wakeup? Or maybe it's just a typo.

In any case, there's never a (good) reason not to use your construct, and in fact the wait function has a variant that does it for you (http://en.cppreference.com/w/cpp/thread/condition_variable/wait).

template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );

which is equivalent to:

while (!pred()) {
     wait(lock);
}
Lakshmi answered 3/4, 2014 at 11:37 Comment(0)
U
2

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.

Urn answered 30/4, 2014 at 20:58 Comment(2)
But OP is asking about C++11 condition variables, which are signal-and-continue. if might work with signal-and-wait, but it's not relevant with C++11 cvars.Lakshmi
@WanderingLogic: OP asked about why the Deitel book contains examples using if and specifically about what the difference is between using if and while. I think my answer is definitely relevant to that question.Urn

© 2022 - 2024 — McMap. All rights reserved.