std::condition_variable和std::condition_variable_any之间有什么区别
What is the difference between std::condition_variable and std::condition_variable_any?
我可能遗漏了一些明显的东西,但我看不出std::condition_variable
和std::condition_variable_any
之间有任何区别。为什么我们两者都需要?
区别在于wait()
函数的参数。std::condition_variable
中的所有等待函数都采用std::unique_lock<std::mutex>&
类型的锁定参数,而std::condition_variable_any
的等待函数都是模板,并且采用Lockable&
类型的锁参数,其中Lockable
是模板参数。
这意味着std::condition_variable_any
可以处理用户定义的互斥锁和锁类型,也可以处理像boost::shared_lock
这样的东西——任何具有lock()
和unlock()
成员函数的东西。
例如
std::condition_variable_any cond;
boost::shared_mutex m;
void foo() {
boost::shared_lock<boost::shared_mutex> lk(m);
while(!some_condition()) {
cond.wait(lk);
}
}
从C++20开始,condition_variable_any
还支持新的jthread类的停止标记。这意味着,如果您有这种类型的条件变量,那么在发出停止请求时,它将放弃互斥锁,而无需编写额外的轮询代码。由于一些技术原因,这个特性在condition_variable
上不起作用,这些原因导致了"争用、死锁和未定义的行为"
void testInterruptibleCVWait()
{
bool ready = false;
std::mutex readyMutex;
std::condition_variable_any readyCV;
std::jthread t([&ready, &readyMutex, &readyCV] (std::stop_token st)
{
while (...)
{
...
{
std::unique_lock lg{readyMutex};
readyCV.wait_until(lg, [&ready] {return ready; }, st);
// also ends wait on stop request for st
}
...
}
});
...
} // jthread destructor signals stop request and therefore unblocks the CV wait and ends the started thread
有关详细信息,请参阅文档:
std::condition_variable
文档
std::condition_variable_any
文档,并具体查看wait
、wait_for
和wait_until
成员函数,这些函数现在在jthreads上接受停止请求。
或者查看最新的jthread和停止令牌C++20提案修订版
std::condition_variable
更专业,因此在不需要std::condition_variable_any
的灵活性时可以更高效。
根据N3290§30.5【线程条件】/1
condition_variable
类提供只能等待类型为unique_lock<mutex>
的对象的条件变量,允许一些平台上的效率。类condition_variable_any
提供了一个通用条件变量可以等待用户提供的锁类型的对象。
实际上,在LLVM的libc++中,condition_variable_any
是使用shared_mutex上更专业的condition_variable
(使用pthread_cond_t)实现的。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 使用std::函数映射对象方法
- 我需要std::condition,但有两个以上的选择