25

我可能遗漏了一些明显的东西,但我看不出std::condition_variableand之间有什么区别std::condition_variable_any。为什么我们两者都需要?

4

2 回答 2

27

不同之处在于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文档,并特别查看现在支持 jthread 上的停止请求的wait,wait_for和成员函数。wait_until

或查看最新的 jthread 并停止令牌 C++20 提案修订

于 2012-01-06T13:28:18.623 回答
20

std::condition_variable更专业,因此当您不需要std::condition_variable_any.

从 N3290 §30.5[thread.condition]/1

Classcondition_variable提供了一个条件变量,它只能等待 type 的对象unique_lock<mutex>,从而在某些平台上实现最大效率。类condition_variable_any提供了一个通用条件变量,可以等待用户提供的锁类型的对象。

实际上,在 LLVM 的 libc++ 中,condition_variable_any是在 shared_mutex 上使用更专业的condition_variable(使用 pthread_cond_t)实现的。

于 2012-01-06T13:16:38.637 回答