【问题标题】:implementation of std::condition_variable::wait_untilstd::condition_variable::wait_until 的实现
【发布时间】:2023-03-13 14:16:01
【问题描述】:

我正在阅读std::condition_variable::wait_until的libstdc++implementation,这里是出处:

template<typename _Clock, typename _Duration>
  cv_status
  wait_until(unique_lock<mutex>& __lock,
     const chrono::time_point<_Clock, _Duration>& __atime)
  {
    // DR 887 - Sync unknown clock to known clock.
    const typename _Clock::time_point __c_entry = _Clock::now();
    const __clock_t::time_point __s_entry = __clock_t::now();
    const auto __delta = __atime - __c_entry;
    const auto __s_atime = __s_entry + __delta;

    return __wait_until_impl(__lock, __s_atime);
  }

template<typename _Clock, typename _Duration, typename _Predicate>
  bool
  wait_until(unique_lock<mutex>& __lock,
     const chrono::time_point<_Clock, _Duration>& __atime,
     _Predicate __p)
  {
    while (!__p())
      if (wait_until(__lock, __atime) == cv_status::timeout)
        return __p();
    return true;
  }

第二个函数循环调用第一个函数,它会做时钟同步操作。所以如果我们调用第二个函数,同步操作可能会运行很多次。每次都需要同步时钟吗?我想代码在第二个功能中只能通过一次同步时钟来改进。我说的对吗?

【问题讨论】:

    标签: c++ multithreading condition-variable


    【解决方案1】:

    我认为你是对的。另一方面,使用 wait_until 的假设通常是事件只会很少发生,并且谓词对于除少数不需要的唤醒实例之外的所有实例都返回 true。因此,重新同步时钟的开销应该是最小的。还要记住,在这种情况下,线程必须已经被唤醒和分页,这可能比查询时钟更昂贵。

    【讨论】:

    • 你能解释一下Remember also that in this case the thread had to be woken up and paged in already, which is probably more expensive than querying a clock.吗?我能明白这一点。
    • @prehistoricpenguin 线程必须被唤醒才能继续执行,这可能比两个时钟调用更昂贵 - 关键是对于一般情况不值得优化。有关 wait_until 的通常假设的更多详细信息,另请参见 Sean 的回答。
    • @BeyerStudios,谢谢你的解释,明白了
    【解决方案2】:

    是的,也不是。

    是的,这段代码可以优化为在循环时不操纵time_points。但是,我不确定这是否真的有必要。

    考虑是什么导致了谓词wait_until 循环。

    notified 时,它会检查谓词以查看是否有工作要做。

    1. 如果谓词返回真,即条件变量保护的条件为真,wait_until 返回true。
    2. 如果超时,wait_until 返回谓词的值,通常为false(否则我们会期望condition_variable 已收到通知)。

    这仅留下循环实际循环的一种情况:通知condition_variable,但谓词返回false。

    这被称为spurious wakeup,几乎不是典型情况,因此不值得优化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 2015-12-22
      相关资源
      最近更新 更多