您能解释一下CLOCK_REALTIME
在Linux上返回的CLOCK_MONOTONIC
和clock_gettime()
时钟之间的区别吗?
如果我需要计算外部源产生的时间戳与当前时间之间的经过时间,那么哪个是更好的选择?
最后,如果我有一个NTP守护程序定期调整系统时间,这些调整如何与CLOCK_REALTIME
和CLOCK_MONOTONIC
中的每一个进行交互?
答案 0 :(得分:200)
CLOCK_REALTIME
表示机器对当前挂钟,时间时间的最佳猜测。正如Ignacio和MarkR所说,这意味着CLOCK_REALTIME
可以随着系统时钟的变化而向前和向后跳转,包括NTP。
CLOCK_MONOTONIC
表示从过去的某个任意固定点开始的绝对经过的挂钟时间。它不受系统时钟变化的影响。
如果您想计算在一台计算机上观察到的两个事件之间经过的时间而没有重新启动,CLOCK_MONOTONIC
是最佳选择。
请注意,在Linux上,CLOCK_MONTONIC
不会测量挂起所花费的时间,尽管它应该通过POSIX定义。您可以使用特定于Linux的CLOCK_BOOTTIME
来获取在暂停期间保持运行的单调时钟。
答案 1 :(得分:32)
Robert Love的书 LINUX系统编程第2版,专门针对您在第11章开头提出的问题,第363页:
单调时间源的重要方面不是当前的 值,但保证时间源是严格线性的 增加,因此可用于计算时间差 两次采样之间
那就是说,我相信他假设这些进程在同一个操作系统实例上运行,所以你可能希望定期运行校准来估计漂移。
答案 2 :(得分:18)
CLOCK_REALTIME
受NTP影响,可以向前和向后移动。 CLOCK_MONOTONIC
不是,并且每剔一个刻度。
答案 3 :(得分:15)
除了Ignacio's answer之外,CLOCK_REALTIME
可以在飞跃中前进,偶尔向后。 CLOCK_MONOTONIC
没有;它只是继续前进(虽然它可能会在重新启动时重置)。
强大的应用程序需要能够容忍CLOCK_REALTIME
偶尔向前跳跃(并且可能偶尔会稍微向后跳跃,尽管这更像是边缘情况)。
想象一下当您暂停笔记本电脑时会发生什么 - CLOCK_REALTIME
在简历后跳转,CLOCK_MONOTONIC
没有。在虚拟机上试一试。
答案 4 :(得分:6)
POSIX 7 指定http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html:
CLOCK_REALTIME
:
此时钟表示测量系统实时的时钟。对于这个时钟,clock_gettime()返回并由clock_settime()指定的值表示自Epoch以来的时间量(以秒和纳秒为单位)。
CLOCK_MONOTONIC
(可选功能):
对于此时钟,clock_gettime()返回的值表示自过去未指定的点(例如,系统启动时间或Epoch)以来的时间量(以秒和纳秒为单位)。系统启动时间后,这一点不会改变。无法通过clock_settime()设置CLOCK_MONOTONIC时钟的值。
clock_settime()
给出了一个重要提示:POSIX系统能够随意改变CLOCK_REALITME
,所以不要依赖它既不连续也不向前流动。 NTP可以使用clock_settime()
实施,只能影响CLOCK_REALITME
。
Linux内核实现似乎将启动时间作为CLOCK_MONOTONIC
的时代:Starting point for CLOCK_MONOTONIC
答案 5 :(得分:2)
对不起,没有信誉将其添加为评论。因此,它是一个补充性答案。
取决于您调用clock_gettime()
的频率,应记住,Linux在VDSO中仅提供了“时钟”中的“一些” (即不需要syscall所有的开销只有一个-只有在Linux添加了防御以防止类似Spectre的攻击时,情况才变得更糟。
尽管clock_gettime(CLOCK_MONOTONIC,...)
,clock_gettime(CLOCK_REALTIME,...)
和gettimeofday()
总是非常快(由VDSO加速),但对于例如CLOCK_MONOTONIC_RAW或任何其他POSIX时钟。
这可能随内核版本和体系结构而改变。
尽管大多数程序不需要注意这一点,但VDSO可能会加速时钟中的延迟尖峰:如果您在内核使用时钟计数器更新共享内存区域时碰到了这些尖峰,则必须等待内核完成。
这是“证明”(GitHub,使机器人远离kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7
答案 6 :(得分:0)
CLOCK_REALTIME 和 MONOTONIC 之间有一个很大的区别。 CLOCK_REALTIME 可以根据 NTP 向前或向后跳转。 默认情况下,NTP 允许时钟速率最多加快或减慢 0.05%,但 NTP 不能导致单调时钟向前或向后跳跃。