我可能遗漏了一些明显的东西,但我看不出std::condition_variable
and之间有什么区别std::condition_variable_any
。为什么我们两者都需要?
2 回答
不同之处在于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_any
文档,并特别查看现在支持 jthread 上的停止请求的wait
,wait_for
和成员函数。wait_until
std::condition_variable
更专业,因此当您不需要std::condition_variable_any
.
从 N3290 §30.5[thread.condition]/1
Class
condition_variable
提供了一个条件变量,它只能等待 type 的对象unique_lock<mutex>
,从而在某些平台上实现最大效率。类condition_variable_any
提供了一个通用条件变量,可以等待用户提供的锁类型的对象。
实际上,在 LLVM 的 libc++ 中,condition_variable_any
是在 shared_mutex 上使用更专业的condition_variable
(使用 pthread_cond_t)实现的。