std :: condition_variable_any是否具有笨拙的语义?

时间:2014-06-25 14:46:48

标签: c++ c++11

使用POSIX条件变量,你会写这样的东西:

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

刚开始看到新的C ++ 11风格时,我很兴奋:

unique_lock<recursive_mutex> g(_consumerCondLock);
_consumerCond.wait( g, [this]() {
    return _doneWaiting;
} );

但是我发现了一个烦恼:上面的谓词lambda是否保证在等待之前运行一次?

2 个答案:

答案 0 :(得分:3)

  

上面的谓词lambda是否保证在任何等待之前运行一次?

必须检查您等待的条件:

  1. 在等待条件变量之前。
  2. spurious wakeups而等待条件变量。
  3. 这就是为什么等待条件变量的规范形式是while循环:

    // lock the mutex
    while(!condition)
        // wait on the condition variable
    

    std::condition_variable::wait为您做的是什么。


    请注意,大多数时候您需要std::condition_variable而不是std::condition_variable_any。后者维护自己的互斥锁,并且在内存和运行时方面更加昂贵。

答案 1 :(得分:3)

是的,它必须在等待之前运行。如果我们查看std::condition_variable_any::wait的引用(与草案C ++标准部分30.5.2 Class condition_variable_any 一致),它会说:

template< class Lock, class Predicate >
void wait( Lock& lock, Predicate pred );

相当于:

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

并说:

  

此异常可用于在等待特定条件变为真时忽略虚假唤醒。