你能解释一下Linux上由clock_gettime()返回的CLOCK_REALTIME和CLOCK_MONOTONIC时钟之间的区别吗?
如果我需要计算外部源产生的时间戳与当前时间之间的经过时间,那么哪个是更好的选择?
最后,如果我有一个NTP守护进程定期调整系统时间,这些调整如何与每个CLOCK_REALTIME和CLOCK_MONOTONIC交互?
你能解释一下Linux上由clock_gettime()返回的CLOCK_REALTIME和CLOCK_MONOTONIC时钟之间的区别吗?
如果我需要计算外部源产生的时间戳与当前时间之间的经过时间,那么哪个是更好的选择?
最后,如果我有一个NTP守护进程定期调整系统时间,这些调整如何与每个CLOCK_REALTIME和CLOCK_MONOTONIC交互?
当前回答
Robert Love的书《LINUX系统编程第二版》在第11章第363页的开头特别回答了你的问题:
单调时间源的重要方面不是电流 值,但保证时间源是严格线性的 递增的,因此对计算时间差很有用 两次抽样之间
也就是说,我相信他假设进程运行在一个操作系统的同一个实例上,所以您可能需要定期运行校准,以便能够估计漂移。
其他回答
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的起点
CLOCK_REALTIME受NTP影响,可以向前和向后移动。CLOCK_MONOTONIC不是,它每滴答一滴答地前进。
不好意思,没有声望可以添加这条评论。所以这是一个互补答案。
取决于你调用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表示机器对当前挂钟时间的最佳猜测。正如Ignacio和MarkR所说,这意味着CLOCK_REALTIME可以随着系统时间(包括NTP)的改变而向前和向后跳转。
CLOCK_MONOTONIC表示从过去某个任意固定点开始经过的绝对时钟时间。它不受系统时间时钟变化的影响。
如果希望计算在一台机器上观察到的两个事件之间的时间,而不需要重新启动,那么CLOCK_MONOTONIC是最佳选择。
注意,在Linux上,CLOCK_MONOTONIC不测量挂起所花费的时间,尽管根据POSIX定义它应该测量。您可以将linux特定的CLOCK_BOOTTIME用于在挂起期间保持运行的单调时钟。