C语言 CLOCK_MONOTONIC如何处理NTP对系统时钟的更改?



精明的工程师使用clock_gettime( CLOCK_MONOTONIC, &my_timspec_struct )获得一个"不受影响"的连续递增的纪元式时钟。通过更改系统时钟。(其中epoch-start没有定义)。

然而,CLOCK_MONOTONIC受到NTP守护进程时间变化(称为时钟"旋转")的影响。

根据CLOCK_MONOTONIC的定义,我们知道它永远不会向后跳。但是它如何减轻NTP带来的变化呢?如果系统时钟突然被NTP设置在过去5个小时,单调时钟是否运行得稍微慢一点,直到它赶上?也许它只是停止了"滴答"直到差异消除?

到底发生了什么?如果它是系统相关的,那么在Linux上会发生什么呢?

我有一些时间相关的代码,失败的硬件时钟是非常脆弱的。它们每隔几分钟就会被重新调整到GPS的位置。虽然这看起来像是不应该影响CLOCK_MONOTONIC,但有时(20分之一)与时序相关的代码不工作。我不能把所有东西都改成CLOCK_MONOTONIC_RAW,因为库(例如:Qt)仍然使用非raw (Ref: Qt 5.15源代码)。

到底发生了什么?如果它是系统相关的,那么在Linux上会发生什么呢?

是否存在CLOCK_MONOTONIC是系统相关的。POSIX要求实现提供的唯一时钟是CLOCK_REALTIME。那么,在Linux上发生了什么呢?

文档对CLOCK_MONOTONIC:

有这样的说明

不能设置的时钟,表示从某时间开始的单调时间未指定起始点。这个时钟不受系统时间的不连续跳跃(例如,如果系统管理员手动修改时钟),但受adjtime(3)和NTP的增量调整。

adjtime()的文档add:

如果delta的调整为正,则系统时钟为加速一个小的百分比(例如,通过添加少量的时间以时钟值为单位(每秒钟),直到调整完毕完成。如果delta的调整为负,则时钟为以类似的方式减速。

由此我们可以得出结论,CLOCK_MONOTONIC以与系统时钟相同的速度移动,这就是为什么当NTP旋转时钟或使用adjtime()时它会受到影响,但当设置系统时钟时它不会更新。它只是单调地不断计数。

最新更新