8

我正在阅读CLOCK_REALTIME和之间的区别CLOCK_MONOTONIC

CLOCK_REALTIME 和 CLOCK_MONOTONIC 的区别?

时间不连续,可以向前跳也可以向后跳:这CLOCK_REALTIME是这个时钟的错误吗?一个给出不一致时间的时钟怎么可能是可靠的?

4

1 回答 1

21

尽管存在缺陷,但 CLOCK_REALTIME 应该是系统对当前 UTC 或民用时间的最佳估计。它是系统能够显示与您查看手表、墙上的时钟、手机或收听广播电台的时间广播等时相同的时间的基础。(显示确实涉及从 UTC 到本地时间的转换;稍后会详细介绍。)

但是,如果 CLOCK_REALTIME 要与现实世界中的 UTC 时间相匹配,那么至少有两个非常重要的问题:

  1. 如果有人不小心把你电脑上的时钟设置错了怎么办?他们将不得不修复它,而修复可能涉及时间跳跃。几乎没有办法解决这个问题,特别是如果错误很大(比如,几小时或几天)。
  2. 不幸的是,大多数计算机无法表示闰秒。因此,当现实世界中出现闰秒时,大多数计算机时钟都必须跳跃一点。

因此,当您读到 CLOCK_REALTIME 可能有不连续性,可能会向前和向后跳跃时,这不是错误,而是一个功能: CLOCK_REALTIME必须具有这些可能性,如果它要应对具有闰秒和偶尔错误时钟的现实世界。

因此,如果您编写的代码应该与现实世界中的时间相匹配,那么 CLOCK_REALTIME 就是您想要的,这是您想要的。但是,理想情况下,如果有时由于某种原因时钟向前或向后跳动,那么您将编写代码以使其表现得相当优雅(不会崩溃或做一些奇怪的事情)。

正如您可能从您引用的另一个问题中知道的那样,CLOCK_MONOTONIC 保证始终以每秒恰好一秒的速度前进,没有跳跃或不连续性,时钟的绝对值并没有多大意义。如果 CLOCK_MONOTONIC 的值为 13:05,这并不意味着它只是在下午 1 点之后,它通常意味着计算机已经启动并运行了 13 小时 5 分钟。

因此,如果您只对相对时间感兴趣,那么 CLOCK_MONOTONIC 就可以了。特别是,如果您想计算某件事花费了多长时间,最好取两个 CLOCK_MONOTONIC 值并减去它们,因为如果在之间。

或者,总而言之,正如人们在评论线程中所说,CLOCK_REALTIME 是绝对时间所需要的,而 CLOCK_MONOTONIC 则更适合相对时间。

现在,还有几点。

如前所述, CLOCK_REALTIME 并不完全是“墙上时间”,因为它实际上以 UTC 交易。它使用自 1970 年以来著名(臭名昭著?)的 Unix/Posix UTC 秒表示。例如,CLOCK_REALTIME 值 1457852399 转换为 2016 年 3 月 13 日 06:59:59 UTC。我住的地方,格林威治以西五个小时,对应于当地时间 01:59:59。但是一秒钟后不是2:00!事实上,1457852400 对应于当地时间 03:00:00,因为那是夏令时开始的时候。

我建议如果你的时钟错了,时间跳跃几乎是修复它的唯一方法,但这并不完全正确。如果你的时钟只是稍微偏离了一点,可以通过逐渐“调整”时间(通过稍微改变时钟频率)来纠正它,这样几分钟或几小时后它就会漂移到正确的时间而不会跳跃。这就是 NTP 试图做的事情,尽管根据其配置,它可能只愿意为非常小的错误这样做。

我说 CLOCK_MONOTONIC 通常是计算机启动并运行的时间。标准不能保证这一点;所有标准都说 CLOCK_MONOTONIC 从某个任意时间点开始计算时间。在确实将 CLOCK_MONOTONIC 实现为系统启动时间的系统上,可以有两种解释:是自启动以来的时间,还是系统启动并运行的时间(即减去它休眠或挂起的任何时间) ? 在许多系统上,还有另一个时钟 CLOCK_BOOTTIME 计算自启动以来的时间(无论是启动还是挂起),而 CLOCK_MONOTONIC 只计算系统启动和运行的时间。

我说,“CLOCK_MONOTONIC 保证总是以每秒一秒的速度前进”,但这也可能不完全正确。如果您的计算机处于时间转换操作的中间,为了尝试逐渐纠正绝对时间错误,实际上可能是 CLOCK_MONOTONIC 暂时以每秒 1.001 秒或每秒 0.999 秒或类似的速度步进那。误差通常很小,但如果它很重要,一些系统还有其他时钟类型,例如CLOCK_MONOTONIC_RAW,应该没有这种扰动。

最后,如果你想跟踪正确的时间,并且你想避免闰秒的跳跃或不连续,你就会遇到问题,因为在传统的 Unix/Linux(和 Windows,以及所有其他)中对闰秒的处理很差计算机系统。在最近的(4.x?)Linux 内核下,有一个 CLOCK_TAI 可能会有所帮助。一些实验系统可能会实现另一个时钟CLOCK_UTC,它可以正确处理闰秒。这两者都有一些其他成本,你必须真正知道你在做什么才能有效地使用它们,至少在今天的支持水平下。有关更多信息,请参阅LEAPSECS 邮件列表

于 2017-01-27T14:01:41.270 回答