std :: condition_variable和std :: condition_variable_any之间有什么区别?

问题描述 投票:19回答:2

我可能缺少明显的东西,但是我看不到std::condition_variablestd::condition_variable_any之间的任何区别。我们为什么同时需要两者?

c++ c++11 std condition-variable
2个回答
16
投票

[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)实现的。


19
投票

区别在于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 documentationstd::condition_variable_anywait成员函数,这些成员函数现在支持jthread上的停止请求。

或签出wait_for

© www.soinside.com 2019 - 2024. All rights reserved.