Answers:
CLOCK_REALTIME
代表机器对当前壁钟时间的最佳猜测。正如Ignacio和MarkR所说,这意味着CLOCK_REALTIME
随着系统时钟(包括NTP)的改变,它可以向前和向后跳跃。
CLOCK_MONOTONIC
表示自过去某个固定点以来经过的绝对时间。它不受系统时间时钟变化的影响。
如果要计算在一台计算机上观察到的两个事件之间的经过时间,而又不进行中间重启,CLOCK_MONOTONIC
则是最佳选择。
请注意,在Linux CLOCK_MONOTONIC
上,虽然通过POSIX定义,它不会测量挂起所花费的时间。您可以将特定CLOCK_BOOTTIME
于Linux 的单调时钟用于挂起期间保持运行。
CLOCK_REALTIME
受NTP影响,并且可以向前和向后移动。CLOCK_MONOTONIC
不是,每跳一跳就跳一次。
System.nanoTime()
用途CLOCK_MONOTONIC
可以测量1000ns或更短的持续时间。也许您在考虑系统时间,有时会限制为毫秒?
除了伊格纳西奥(Ignacio)的回答外,CLOCK_REALTIME
还可以飞跃向前,偶尔向后飞。CLOCK_MONOTONIC
两者都不做;它只是继续前进(尽管它可能会在重新启动时重置)。
一个健壮的应用程序需要能够容忍CLOCK_REALTIME
偶尔的向前跳跃(也许偶尔会非常轻微地向后跳跃,尽管这更多的是一种极端情况)。
想象一下,当您挂起笔记本电脑时会发生什么- CLOCK_REALTIME
在履历表之后向前跳,CLOCK_MONOTONIC
而不会。在虚拟机上尝试。
CLOCK_PROCESS_CPUTIME_ID
。快速测试:$ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'
-> 706724.117565279 该数字与Linux上的系统正常运行时间相匹配,但该标准表明它是任意的。
CLOCK_MONOTONIC
一句,我不认为通过挂起/恢复停止的Linux行为符合POSIX。应该是从过去的某个固定时间开始的时间,但是在挂起/恢复上停止时钟会破坏该时间。
POSIX 7引号
POSIX 7在http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html上都指定了这两项:
CLOCK_REALTIME
:
该时钟表示测量系统实时时间的时钟。对于此时钟,clock_gettime()返回的值和clock_settime()指定的值表示自纪元以来的时间量(以秒和纳秒为单位)。
CLOCK_MONOTONIC
(可选功能):
对于此时钟,clock_gettime()返回的值表示自过去未指定的点(例如,系统启动时间或纪元)以来的时间量(以秒和纳秒为单位)。在系统启动时间之后,这一点不会改变。不能通过clock_settime()设置CLOCK_MONOTONIC时钟的值。
clock_settime()
给出了一个重要提示:POSIX系统能够CLOCK_REALITME
随其进行任意更改,因此不要依赖于它既不连续也不向前。NTP可以使用实现clock_settime()
,并且只会影响CLOCK_REALITME
。
Linux内核实现似乎以启动时间为以下时间CLOCK_MONOTONIC
:CLOCK_MONOTONIC的起点
抱歉,没有信誉将其添加为评论。因此,它是一个补充性答案。
根据您调用的频率clock_gettime()
,您应该记住,Linux仅在VDSO中提供了一些 “时钟”(即,不需要系统调用,而所有开销只有一个-只会在添加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