首页 > 解决方案 > 使用 chrono 库获取系统时间不准确

问题描述

我使用 std::chrono 以 500 毫秒的间隔对系统时间进行采样。在每个样本上,我从上一次减去当前时间,并累积结果。但是 1 小时后,总累积时间快了 50 毫秒左右。有人知道原因吗?获取系统时间的代码如下:

void serverTimeResponse(long serverTime) {        
     long localTime =(long)std::chrono::duration_cast<std::chrono::microseconds(now.time_since_epoch()).count();        
      long duration = localtime - serverTime;        
    writeToCsvFile(duration); 

} 

serverTimeResponse 将每 500 毫秒调用一次,因为服务器将通过套接字返回,我将持续时间记录到 csv 文件中,1 小时后,我看到最后一行持续时间比 csv 文件中的第一行持续时间多 50 毫秒。我怀疑 chrono 库在获取系统时间方面是否存在问题。

在 ubuntu 18.04 上运行

标签: c++ubuntuchrono

解决方案


我可以理解您想要实现的目标,但您可能会遇到与操作系统线程调度相关的问题。您还没有制作一个最小的可重现示例,所以我假设您正在使用例如:

std::this_thread::sleep_for(500ms);

如果是这种情况,那么您将受操作系统的摆布,以便在正确的时间内休眠。

每 500 毫秒采样一次当前时间并减去最后一次,这听起来不错。但是,当您睡眠 500 毫秒时,操作系统会安排程序在该数字附近的某个时间被唤醒。请记住,操作系统不是实时的。他们无法保证您的应用程序将休眠 500 毫秒。

您的样本之间的所有这些小的睡眠时间差异都会加起来。下面是一些计算:

You are sampling every 500ms for 1hr:

1000ms * 60s * 60m = 3600000ms  // 1hr in milliseconds
3600000ms / 500ms = 7200        // 7200 samples @ 500ms each
50ms / 7200 =  0.006944444ms    // or 6.944444us error per sample

如您所见,有一个 6.9us 的微小误差。所以操作系统几乎睡了 500 毫秒,但并没有完全睡着。这些小错误加起来,当涉及到 EXACT 睡眠时,您无能为力。


推荐阅读