std::condition_variable_any是否有尴尬的语义?
Does std::condition_variable_any have awkward semantics?
使用POSIX条件变量,您可以这样写:
while (!_doneWaiting) {
wait(lock);
}
一开始当我看到c++ 11的新风格时,我很兴奋:
unique_lock<recursive_mutex> g(_consumerCondLock);
_consumerCond.wait( g, [this]() {
return _doneWaiting;
} );
但是一个烦恼发生在我身上:上面的谓词lambda保证在任何等待发生之前运行一次吗?
上面的谓词lambda是否保证在任何等待发生之前运行一次?
必须检查您等待的条件:
- 在等待条件变量之前。
- 由于虚假唤醒而等待条件变量后。
这就是为什么等待条件变量的标准形式是while
循环:
// lock the mutex
while(!condition)
// wait on the condition variable
这就是std::condition_variable::wait
为你做的。
注意,大多数情况下您需要std::condition_variable
而不是std::condition_variable_any
。后者维护自己的互斥锁,并且在内存和运行时间方面更昂贵。
是的,它必须在等待之前运行。如果我们看一下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);
}
说:
此重载可用于在等待特定条件变为真时忽略虚假唤醒。
相关文章:
- C++ 移动语义是否在任何情况下都能节省资源?
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 如果没有带有函数签名的 rvalue 参数,是否会执行 C++ 11 中的移动语义?
- 移动语义是否C++ C 缺少的东西
- 标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
- 默认情况下,返回是否使用移动或复制语义
- 放置 new 的返回值与其操作数的强制转换值之间是否存在(语义)差异
- 移动语义是否只是一个浅层副本并将其他人的指针设置为 null?
- 每次复制实现移动分配的非 const 对象时,我是否总是获得移动语义
- C++11是否允许(不要求)volatile关键字的发布/获取语义
- 在C++11中抛出异常时,是否使用移动语义
- 返回本地对象是否需要移动语义
- Clang/C2 是否使用与 Clang/LLVM 相同的语义分析和 AST?
- 首先创建字符串,然后通过移动语义将其添加到 vector 或在 vector 中创建元素是否具有内存效率
- 是否可以将此 Rust 代码编写为语义等效的C++代码
- “std::memory_order_aquire”的语义是否需要x86/x8_64上的处理器指令
- atomic_thread_fence(memory_order_seq_cst)是否具有完整内存屏障的语义?
- 局部变量的初始化:这些方法在语义上是否不同
- 如果没有定义Move语义(Move构造函数和Move赋值操作符),编译器是否默认优化
- 抢占式多任务是否会干扰c++ 11的发布获取语义?