【问题标题】:What is the difference between std::condition_variable and std::condition_variable_any?std::condition_variable 和 std::condition_variable_any 有什么区别?
【发布时间】:2012-01-06 13:14:16
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    区别在于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 并特别查看 waitwait_forwait_until 成员函数,它们现在支持 jthread 上的停止请求。

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

    【讨论】:

      【解决方案2】:

      std::condition_variable 更专业,因此在您不需要std::condition_variable_any 的灵活性时可以更高效。

      来自 N3290 §30.5[thread.condition]/1

      condition_variable 类提供 只能等待unique_lock&lt;mutex&gt; 类型的对象的条件变量,允许最大 在某些平台上的效率。 condition_variable_any 类提供了一个通用条件变量 可以等待用户提供的锁类型的对象。

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

      【讨论】:

      • 谢谢。这让我快疯了。我只是看不到它。
      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 2014-07-22
      • 2023-04-09
      • 2020-10-16
      • 2020-09-30
      • 2021-10-16
      • 2015-07-18
      • 2019-02-26
      相关资源
      最近更新 更多