7

如果std::condition_variable可以由于虚假唤醒而发出信号(并且我们不能确定我们需要的条件是否真的得到满足),为什么 C++ 标准库提供wait()没有谓词的方法重载?可以使用这种行为的场景是什么?

4

3 回答 3

7

假设一个复杂的条件A || B。当条件的任何部分为真时,应执行适当的操作,actionA或。actionB

使用谓词版本,代码可能如下:

cond.wait(lock, []{return (A || B);});
if(A) {
    actionA();
}
else {
    actionB();
}

但是如果使用非谓词等待,代码可能会更快:

while(true)
{
    if(A) {
         actionA();
         break;
    }
    else if(B) {
         actionB();
         break;
    }
    cond.wait(lock);
}

请注意,与第一个变体不同,现在每个条件部分都被评估一次。

还有更复杂的情况,条件不能写在单个表达式中。

于 2016-01-26T11:57:46.727 回答
4

为什么 C++ 标准库在没有谓词的情况下提供 wait() 方法的重载

的谓词版本wait等价于:

while (!pred()) {
    wait(lock);
}

如果您需要在等待之前和/或之后执行更复杂的代码,您可能希望wait不使用谓词。

于 2016-01-26T12:11:34.547 回答
3

我想在某些情况下,虚假唤醒并不是世界末日。

例如,考虑一个生产者-消费者批处理系统,其中一些线程应该在队列中有至少 100 条消息时唤醒并处理它们。

考虑到虚假唤醒,它有时可能会收到少于 100 条消息。这种差异可能无法保证条件函数的开销和额外复杂性。

于 2016-01-26T12:02:36.863 回答