你能解释一下Linux上由clock_gettime()返回的CLOCK_REALTIME和CLOCK_MONOTONIC时钟之间的区别吗?

如果我需要计算外部源产生的时间戳与当前时间之间的经过时间,那么哪个是更好的选择?

最后,如果我有一个NTP守护进程定期调整系统时间,这些调整如何与每个CLOCK_REALTIME和CLOCK_MONOTONIC交互?


当前回答

CLOCK_REALTIME和MONOTONIC之间有一个很大的区别。CLOCK_REALTIME可以根据NTP向前跳或向后跳。 缺省情况下,NTP允许时钟速率的加速或减速不超过0.05%,但NTP不能使单调时钟向前或向后跳变。

其他回答

不好意思,没有声望可以添加这条评论。所以这是一个互补答案。

取决于你调用clock_gettime()的频率,你应该记住,在VDSO中只有一些“时钟”是由Linux提供的(即不需要一个系统调用的所有开销——当Linux添加防御来防止类似幽灵的攻击时,这只会变得更糟)。

虽然clock_gettime(CLOCK_MONOTONIC,…),clock_gettime(CLOCK_REALTIME,…)和gettimeofday()总是非常快(由VDSO加速),但对于例如clock_单调ic_raw或任何其他POSIX时钟来说不是这样的。

这可以随着内核版本和体系结构的变化而改变。

尽管大多数程序不需要注意这一点,但是VDSO加速的时钟可能会出现延迟峰值:如果您在内核用时钟计数器更新共享内存区域时恰好击中它们,那么它必须等待内核完成。

以下是“证据”(GitHub,以防止机器人接近kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7

除了伊格纳西奥的答案,CLOCK_REALTIME还可以向前跳跃,偶尔也可以向后跳跃。CLOCK_MONOTONIC两者都没有;它只是继续前进(尽管它可能在重新启动时重置)。

一个健壮的应用程序需要能够容忍CLOCK_REALTIME偶尔向前跳跃(也许向后非常轻微,非常偶尔,尽管这是一个边缘情况)。

想象一下当你挂起你的笔记本电脑时会发生什么——CLOCK_REALTIME跟随resume向前跳转,而CLOCK_MONOTONIC没有。在虚拟机上试试。

CLOCK_REALTIME受NTP影响,可以向前和向后移动。CLOCK_MONOTONIC不是,它每滴答一滴答地前进。

POSIX 7引号

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_MONOTONIC时钟的值不能通过clock_settime()来设置。

clock_settime()给出了一个重要的提示:POSIX系统能够任意地改变CLOCK_REALITME,所以不要依赖于它既不连续也不向前流动。NTP可以使用clock_settime()实现,并且只能影响CLOCK_REALTIME。

Linux内核实现似乎将引导时间作为CLOCK_MONOTONIC的epoch: CLOCK_MONOTONIC的起点

Robert Love的书《LINUX系统编程第二版》在第11章第363页的开头特别回答了你的问题:

单调时间源的重要方面不是电流 值,但保证时间源是严格线性的 递增的,因此对计算时间差很有用 两次抽样之间

也就是说,我相信他假设进程运行在一个操作系统的同一个实例上,所以您可能需要定期运行校准,以便能够估计漂移。