我可能遗漏了一些明显的东西,但我看不出std::condition_variableand之间有什么区别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)实现的。