在Linux版本早于2.6.28的clock_monotonic_raw替代品

时间:2016-01-18 08:26:39

标签: linux time

clock_monotonic_raw仅在Linux 2.6.28开始时受支持。

还有另一种方法可以获得单调时间,不受NTP调整或调整后的增量调整吗? 我不能使用clock_monotonic,因为它受NTP&的adjtime。

1 个答案:

答案 0 :(得分:1)

仔细查看CLOCK_MONOTONIC,而不仅仅是CLOCK_MONOTONIC_RAW。我想在条件等待时使用CLOCK_MONOTONIC_RAW,但发现它不受支持(Fedora 25 / Linux 4.10.17)。

情况模糊不清,但就我目前的理解而言,Linux的结果是:

  1. CLOCK_MONOTONIC_RAW是您最接近以恒定频率运行的方波累加器。但是,这比你想象的要好得多。

  2. CLOCK_MONOTONIC基于CLOCK_MONOTONIC_RAW,应用了一些渐进的频率校正,使其最终超越或落后于其他时钟参考。 NTP和adjtime都可以进行这些修正。但是,为了避免破坏软件构建中的内容,时钟仍然保证单调推进

  3. “adjtime()对时钟的调整是以时钟总是单调增加的方式进行的。” - adjtime手册页

    “你撒谎的私生子。” --me

    1. 是的 - 这是计划,但在2.6.32.19之前的内核版本中存在错误;请参阅此处的讨论:https://stackoverflow.com/a/3657433/3005946,其中包含指向修补程序的链接,如果这会影响您。我很难说出那个bug的最大错误是什么(我真的非常想知道)。

    2. 即使在4.x内核中,大多数POSIX同步对象似乎都不支持CLOCK_MONOTONIC_RAW或CLOCK_MONOTONIC_COARSE。我发现了这个问题。总是错误检查你的* _setclock电话。

    3. POSIX信号量(sem_t)根本不支持任何单调时钟,这是令人愤怒的。如果你需要这个,你将不得不使用条件等待自己滚动。 (作为奖励,这样做可以让您拥有负初始水平的信号量,这可能很方便。)

    4. 如果您只是想让同步对象的等待函数永远保持死锁状态,并且您有三秒钟的救助,那么您可以使用CLOCK_MONOTONIC并将其称为一天 - 调整CLOCK_MONOTONIC有效地进行抖动校正,远低于您的精度要求。即使在有缺陷的实现中,CLOCK_MONOTONIC也不会向后跳一小时或类似的东西。同样,相反的是,adjtime这样的事情调整了时钟的频率,使其逐渐超越或落后于其他一些并行运行的时钟。

    5. CLOCK_REALTIME实际上是CLOCK_MONOTONIC,并应用了一些其他校正因子。或者相反。无论如何,它实际上都是一样的。重要的是,如果您的应用程序有可能改变时区(移动车辆,飞机,船舶,巡航导弹,滑旱冰机器人)或遇到行政时钟调整,您绝对不应该使用CLOCK_REALTIME或任何需要它的东西。如果服务器使用夏令时而不是UTC,则同样如此。但是,如果需要,使用UTC的固定服务器可以使用CLOCK_REALTIME来避免粗略的死锁。除非你使用2.6之前的内核并且别无选择,否则请避免这种情况。

    6. CLOCK_MONOTONIC_RAW不是您想要用于时间戳的东西。它尚未进行抖动校正等。它可能适用于DAC和ADC等,但不是您想要用于在人类可识别的时间尺度上记录事件的内容。我们有NTP是有原因的。

    7. 希望这有帮助,我当然可以理解挫折感。