predicate for condition variable

心已入冬 提交于 2021-02-04 19:10:10

问题


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?


回答1:


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);
}



回答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.



来源:https://stackoverflow.com/questions/22837254/predicate-for-condition-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!