c++ - std::condition_variable 和 std::condition_variable_any 有什么区别?

标签 c++ multithreading c++11 std condition-variable

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

最佳答案

区别在于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_any documentation并具体查看wait , wait_forwait_until现在支持 jthread 上的停止请求的成员函数。

或查看 latest jthread and stop token C++20 proposal revision

关于c++ - std::condition_variable 和 std::condition_variable_any 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8758353/

相关文章:

c++ - 获取 "terminating with uncaught exception of type std::length_error: vector"错误 C++

c# - 将(多个)文件复制到多个位置

c - 无法使用线程概念显示进度条?

c++ - 是否有一个标准方法来确保一段代码在全局范围内执行?

c++ - 诊断互斥锁相关瓶颈的正确方法

java - Junit5的TestReporter线程安全吗?

c++ - 是否可以让 Qt Creators Ui 设计器为其无法识别的类创建插槽?

c++ - 客户端断开连接后处理服务器应用程序中的线程

c++ - 这个签名中的第二个参数是什么意思?

c++ - 使用模板有条件地生成 C++ 类的数据成员