计时器环绕问题



以下代码是否正确

添加事件:

pushEvent(std::chrono::steady_clock::now() + dt, event_obj);

在事件循环中:

//...
auto now=std::chrono::steady_clock::now();
if(event.expireTime<=now)
    {
    event.fire();
    }
//...

我有点担心环绕行为,因为我知道至少有两个错误 [1] 和 [2],这是由于时间计数器中的环绕而引入的。我想到的可能会发生:

  • 事件提前触发,因为std::chrono::steady_clock::now() + dt将小于std::chrono::steady_clock::now()

  • 该事件触发得很晚,因为std::chrono::steady_clock::now()可能已经有了环绕。

    [1] https://www.cnet.com/news/windows-may-crash-after-49-7-days/

    [2] https://github.com/jackaudio/jack2/issues/150

您可以使用

steady_clock::time_point::max().time_since_epoch()检查steady_clock::time_point的范围。 这将返回一个chrono::duration,这是自steady_clock纪元以来的最长时间量。 纪元本身未指定。 然而:

auto time_left = steady_clock::time_point::max() - steady_clock::now();

给你剩下的时间,直到max()被击中。 可以通过以下方式检查time_left的确切单位:

using D = decltype(time_left);
std::cout << D::period::num << '/' << D::period::den << 'n';

在每个平台上,这输出:

1/1000000000

这意味着单位是纳秒。 因此,您可以:

std::cout << time_left.count() << "nsn";

如果您愿意使用我的免费,仅标题日期/时间库,它将为您进行内省,您可以执行以下操作:

using date::operator<<;
std::cout << time_left << "n";

对我来说,这输出:

9221890448824928278ns

大约是292年。 如果你的代码在我的平台上运行,它可能会在 292 年内完成。 您的平台可能相似,这就是您可以对其进行测试的方式。

相关内容

  • 没有找到相关文章

最新更新