使用chrono库获取不准确的系统时间

问题描述

我正在使用std :: chrono以500ms的间隔对系统时间进行采样。在每个样本上,我从上次时间中减去当前时间,然后累加结果。但是,在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将每500ms调用一次,因为服务器将通过套接字返回,我将持续时间记录到csv文件中,经过1小时,我看到最后一行的持续时间比csv文件中的第一行持续时间长50ms。我怀疑chrono库是否存在获取系统时间的问题。

在ubuntu 18.04上运行

解决方法

我可以理解您要实现的目标,但是您可能会遇到与操作系统的线程调度有关的问题。您尚未制作出最小的可复制示例,所以我假设您正在使用例如:

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毫秒,但并没有。这些小错误加起来,就完全睡眠而言,您无能为力。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...