bool 版本的 boost::condition_variable::wait_until 使用谓词如何表现?

Posted

技术标签:

【中文标题】bool 版本的 boost::condition_variable::wait_until 使用谓词如何表现?【英文标题】:How does bool version of boost::condition_variable::wait_until using a predicate behave? 【发布时间】:2017-12-16 21:45:59 【问题描述】:

尝试使用:

bool
wait_until(
    unique_lock<mutex>& lock,
    const chrono::time_point<Clock, Duration>& t,
    Predicate pred);

boost::condition_variable::wait_until 的形式(长篇大论为什么不是std)。该文档指出,这样做的效果是“好像:”

while(!pred())

    if(!wait_until(lock,abs_time))
    
        return pred();
    

return true;

但是wait_untilwait_until(lock,abs_time) 形式实际上返回了一个cv_status 类型,定义为:

enum class cv_status;

  no_timeout,
  timeout
;

由于cv_status 类型不能隐式转换为bool(对吗?),“As-if”中的if(!wait_until(lock,abs_time)) 条件究竟意味着什么?我想它是在说“如果等待超时,则返回谓词的值”,但我没有从if 语句的形式和wait_untilcv_status 返回类型中得到。

现在,std 文档“等效于”似乎正是我所期望的:

while (!pred()) 
    if (wait_until(lock, abs_time) == std::cv_status::timeout) 
        return pred();
    

return true;

因此可以安全地假设 boost 文档只是有点偏离并且实现如 std 文档中所述吗?

【问题讨论】:

如果谓词的结果在超时前返回true,超时返回false。 IE。每次设置控制变量时都会运行谓词,如果谓词为真则返回真,如果为假则等待重试。如果整个操作在谓词为真之前超时,则返回假。虽然 boost 对 stl 有所贡献,但 boost 不是 stl。 感谢您的输入,但我认为您在谈论 wait_until(lock, abs_time, pred) 表单,我理解,但我实际上是在询问“As-”中提到的 wait_until(lock, abs_time) 表单if”(解释)部分在文档中。该表单不返回 bool - 它返回 boost::cv_status 类型。如果有人假设 cv_status::no_timeout 被强制转换为 0(假)而 cv_status::timeout 被强制转换为 1(真),那么解释与我认为的实际行为完全相反。 @jeff 作为猜测,boost 的设计考虑了枚举而不是枚举类。文档反映了这一点。 【参考方案1】:

您可能混淆了文档¹。

在此示例代码中:Live On Coliru(输出:“Nay”)

#include <boost/thread.hpp>
#include <iostream>

int main()

    boost::mutex m;
    boost::condition_variable cv;

    boost::unique_lock<boost::mutex> lk(m);
    if (cv.wait_until(lk,
            boost::chrono::high_resolution_clock::now() + boost::chrono::seconds(1), 
            []  return false; ))
    
        std::cout << "Yay\n";
     else 
        std::cout << "Nay\n";
    

wait_until 的返回类型实际上是 bool。该调用的实现实际上是:

    template <class Clock, class Duration, class Predicate>
    bool
    wait_until(
            unique_lock<mutex>& lock,
            const chrono::time_point<Clock, Duration>& t,
            Predicate pred)
    
        while (!pred())
        
            if (wait_until(lock, t) == cv_status::timeout)
                return pred();
        
        return true;
    

如您所见,它显式处理cv_status 类型。

除了看起来 [原文如此] 之外,“As-if”代码是假定返回值类型为 bool 的伪代码。我同意这在技术上是“不正确的”。


¹ 见

【讨论】:

感谢您的意见,不胜感激。我绝对是迂腐的。我希望在文档中做一件事(也许是,但我错过了):确保您的谓词不需要锁定您的条件变量正在使用的同一个互斥锁,否则打开 while(!pred()) 往往需要,嗯,嗯, 永远:-)。

以上是关于bool 版本的 boost::condition_variable::wait_until 使用谓词如何表现?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须为 boost::condition_variable 设置一个 boost::mutex?

boost::condition_variable::notify_one() 的行为

boost::condition_variableboost::time_wait使用方法

Boost线程禁用

C++ 条件变量范围

提升线程 notify_all() 和 sleep()