从Linux内核版本3.10开始,函数clock_gettime()
现在接受CLOCK_TAI
。
我没有找到这个钟的详细描述。它的年代是什么?
EDIT 1:刚刚比较了CLOCK_REALTIME和CLOCK_TAI在我的Linux 3.19操作系统上的输出,它返回完全相同的值(1442582497)!CLOCK_REALTIME在闰秒时是否递减?
EDIT 2:根据本文,CLOCK_TAI和(名字不好的)CLOCK_REALTIME之间的区别应该是闰秒数。
EDIT 3: CLOCK_TAI
和CLOCK_REALTIME
同时存在的原因已在EDIT 2中引用的文章中解释。重点是我。
对于可以使用TAI时间而不是UTC时间的应用程序,内核提供了一个特殊的CLOCK_TAI时钟,它包含闰秒,并且不需要在闰秒之后进行校正,从而完全避免了时间向后跳转的问题。它被实现为一个时钟,运行在与CLOCK_REALTIME固定的整数偏移量上,当CLOCK_REALTIME时钟在闰秒后退时,该偏移量自动增加1。它是在Linux内核版本3.10中引入的,并且可以在RHEL7中提供的内核中使用。请注意,CLOCK_REALTIME的偏移量在启动时初始化为零,ntpd和chronyd都没有将其默认设置为正确的值(目前为35)。在应用程序中切换到CLOCK_TAI当然需要修改代码,可能还需要修改所有使用Unix时间表示的协议。
编辑4:这个在问Ubuntu上得到的答案澄清了一切。
CLOCK_TAI is basically designed as CLOCK_REALTIME(UTC) + tai_offset.
所以timeval/timespec的usec/nsec部分应该是相同的
CLOCK_MONOTONIC: Zeroed at boot.
CLOCK_TAI = CLOCK_MONOTONIC + tai_mon_offset
CLOCK_REALTIME(UTC) = CLOCK_TAI - tai_utc_offset
但是由于性能问题(CLOCK_REALTIME是什么应用程序在Linux中,我们实际上将其结构为:
CLOCK_REALTIME: Initialized at boot from RTC
CLOCK_MONOTONIC: CLOCK_REALTIME - wall_to_monotonic
CLOCK_TAI: CLOCK_REALTIME + tai_offset
所以CLOCK_REALTIME and CLOCK_TAI return the same because the kernel parameter tai_offset is zero.
使用adjtimex(timex tmx)
检查并读取值。我认为ntpd
将设置它,如果它是足够新的(>4.2.6
),并有一个闰秒文件。它也可以从上游服务器获得它,但我还没有能够验证。调用adjtimex()
可以在作为root运行时手动设置tai_offset
。
我这里和这里的参考