c++ - 使用 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 上运行
解决方案
我可以理解您想要实现的目标,但您可能会遇到与操作系统线程调度相关的问题。您还没有制作一个最小的可重现示例,所以我假设您正在使用例如:
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 睡眠时,您无能为力。
推荐阅读
- spark-ar-studio - 音频在 Spark-ar 中有效,但在 Instagram 中无效
- mysql - MySQL Group By 用于排序表
- php - 如何在laravel中使用与数组的关系
- javascript - 如何使我的搜索栏在聚焦时不会折叠?
- powershell - 查找两个文件的差异并附加到第一个文件 powershell
- c# - 如何在 .NET Core Web API 的 Dictionary 键中将枚举转换为 int
- javascript - 如何通过执行切片用地图重写推送?
- reactjs - 在类组件中反应 useEffect 等效项
- deep-learning - 是否可以在 FPGA 上训练 YOLO - 对象检测模型?
- javascript - next() 在 Express 4 上不起作用,错误 [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client