wait_until behavior for time_point::max

wait_until behavior for time_point::max

本文关键字:point max time for until behavior wait      更新时间:2023-10-16

在一个嵌入式平台上,我遇到了一个问题,当等待一个条件直到time_point<clock>::max()时,程序完全进入一个占用CPU的忙循环。

我正在运行的程序是:

#include <mutex>
#include <condition_variable>
#include <iostream>
int main() {
  std::mutex mutex;
  std::condition_variable condition;
  using namespace std::chrono;
  using clock = steady_clock;
  for (;;) {
    auto forever = time_point<clock>::max();
    std::unique_lock<std::mutex> lock(mutex);
    std::cout << "Now waiting" << std::endl;
    condition.wait_until(lock, forever);
    std::cout << "Now waking up" << std::endl;
  }
  return 0;
}

我很确定这是一个bug,并且在我主机的编译器(g++ 4.7)上运行它,应用程序的行为与我预期的一样(永远阻塞)。在编写bug报告时,我想附加一个ideone示例来演示这个问题,但是ideone也会遇到一个忙循环:

http://ideone.com/XPy0Wn

现在我不确定谁是正确的。当第二个参数为time_point<clock>::max()时,是否存在wait_until条件的标准定义?

您可能会观察到一个(愚蠢的)稳定时钟到系统时钟时间的转换:

#include <chrono>
#include <iostream>
using namespace std::chrono;
time_t silly_steady_clock_to_time_t( steady_clock::time_point t )
{
    return system_clock::to_time_t(system_clock::now()
         + (t - steady_clock::now()));
}
int main() {
      auto system_time = system_clock::to_time_t(system_clock::now());
      auto forever = time_point<steady_clock>::max();
      auto forever_time = silly_steady_clock_to_time_t(forever);
      std::cout << ctime(&forever_time) << 'n';
      std::cout << ctime(&system_time) << 'n';
      return 0;
}
输出:

Fri Jun 16 11:40:31 1724
Tue Sep 27 15:44:54 2016

注意:稳态的forever_time是过去式

clock更改为using clock = system_clock;将解决此问题。

正如评论中提到的,如果您想尝试跟踪它,您应该检查对wait_until调用的返回类型。
可以是std::cv_status::timeoutstd::cv_status::no_timeout
通过这样做,你将能够理解那里发生了什么。

如标准所述,返回类型遵循以下规则:

如果abs_time指定的绝对超时已过期,则为cv_status::timeout,否则为cv_status::no_timeout

此外:

当调用notify_one(),调用notify_all(), abs_time指定的绝对超时过期或虚假时,该函数将解除阻塞。

最后一个可能是你的情况,它不太可能是一个bug。
您应该寻找导致这些虚假唤醒的原因。