【问题标题】:What is the use of CLOCK_REALTIME?CLOCK_REALTIME 有什么用?
【发布时间】:2017-01-27 12:39:37
【问题描述】:

我正在阅读 CLOCK_REALTIMECLOCK_MONOTONIC 之间的区别

Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

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

【问题讨论】:

  • 夏令时是挂钟时间的一个例子,它可能会前后跳跃。另请注意,该答案清楚地表明这是系统的猜测 - 当它确定先前的猜测不正确时,它会再次猜测。
  • 取决于你需要它的用途和你打算用它做什么,有时,有一个时间戳很有用(想想日志记录),或者你想给一些对象加上时间戳(创建,完成交易等)知道某事的时间是有用的。注意:这绝不意味着适合性能测量...
  • 计算机是如何猜测时间的?它检查它的手表。或者它可能在互联网上询问。这仍然是一个猜测,因为互联网可能比平时慢。无论如何,它不是,就像,你知道的,它真的必须猜测
  • @Bionix1441,这就是全部点,每种时钟类型都有不同的用途,单调时钟适合测量经过的时间(想想 - 多久 i> 做了什么?),实时时钟可用作时间指示器(想想 何时 发生了什么事情?)实时时钟(由于它的设计)不适合测量经过的时间(如它可以前后移动。)
  • @RadLexus 听起来你现在明白了,但对于其他想知道的人来说:人类可读的时间在 DST 转换时跳跃,但 CLOCK_REALTIME(如它所基于的 Unix/Posix 时间)没有。 CLOCK_REALTIME 是 UTC,没有时区或 DST。它稍后会转换为人类可读的时间,这就是时区和 DST 偏移量的引入。

标签: c clock gettime


【解决方案1】:

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

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

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

所以当你读到 CLOCK_REALTIME 可能有不连续性,可能向前和向后跳跃时,这不是一个错误,而是一个特性:CLOCK_REALTIME 必须有这些可能性,如果它是为了应对真实的世界上有闰秒和偶尔出错的时钟。

因此,如果您编写的代码应该与现实世界中的时间相匹配,那么 CLOCK_REALTIME 就是您想要的,这是您想要的。不过,理想情况下,您编写代码的方式应使其行为合理(不会崩溃或做一些奇怪的事情),如果偶尔由于某种原因时钟向前或向后跳动。

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

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

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

现在,还有几点。

如前所述,CLOCK_REALTIME 并不完全是“墙上时间”,因为它实际上以 UTC 交易。它使用自 1970 年以来著名(臭名昭著?)的 Unix/Posix 表示 UTC 秒。例如,CLOCK_REALTIME 值 1457852399 转换为 2016 年 3 月 13 日 06:59:59 UTC。我住的地方,格林威治以西 5 小时,对应于当地时间 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 mailing list 了解更多信息。

【讨论】:

  • 绝妙的答案。以易于理解的方式涵盖所有基础。
  • “这就是 NTP 试图做的事情,尽管事实证明它只愿意为非常小的错误(比如,我认为不到一秒)这样做。” i> 这完全可以在您的 NTP 客户端中配置
  • @LightnessRacesinOrbit 我认为这取决于您的 NTP 客户端。我有权威的说法是,只有当错误小于 128 毫秒时,参考实现才会发生变化,并且没有办法重新配置这个值。
  • @LightnessRacesinOrbit 但我认为其他 ntp 实现不那么挑剔,所以我调整了措辞。
  • @SteveSummit 很棒的答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2022-01-24
  • 1970-01-01
  • 2018-02-16
  • 2017-08-23
  • 2012-06-10
相关资源
最近更新 更多