我可能缺少明显的东西,但是我看不到std::condition_variable
和std::condition_variable_any
之间的任何区别。我们为什么同时需要两者?
[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)实现的。
区别在于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
documentation
[std::condition_variable
,现在专门研究std::condition_variable_any
documentation,std::condition_variable_any
和wait
成员函数,这些成员函数现在支持jthread上的停止请求。
或签出wait_for