clock_monotonic_raw仅在Linux 2.6.28开始时受支持。
还有另一种方法可以获得单调时间,不受NTP调整或调整后的增量调整吗? 我不能使用clock_monotonic,因为它受NTP&的adjtime。
答案 0 :(得分:1)
仔细查看CLOCK_MONOTONIC,而不仅仅是CLOCK_MONOTONIC_RAW。我想在条件等待时使用CLOCK_MONOTONIC_RAW,但发现它不受支持(Fedora 25 / Linux 4.10.17)。
情况模糊不清,但就我目前的理解而言,Linux的结果是:
CLOCK_MONOTONIC_RAW是您最接近以恒定频率运行的方波累加器。但是,这比你想象的要好得多。
CLOCK_MONOTONIC基于CLOCK_MONOTONIC_RAW,应用了一些渐进的频率校正,使其最终超越或落后于其他时钟参考。 NTP和adjtime都可以进行这些修正。但是,为了避免破坏软件构建中的内容,时钟仍然保证单调推进:
“adjtime()对时钟的调整是以时钟总是单调增加的方式进行的。” - adjtime手册页
“你撒谎的私生子。” --me
是的 - 这是计划,但在2.6.32.19之前的内核版本中存在错误;请参阅此处的讨论:https://stackoverflow.com/a/3657433/3005946,其中包含指向修补程序的链接,如果这会影响您。我很难说出那个bug的最大错误是什么(我真的非常想知道)。
即使在4.x内核中,大多数POSIX同步对象似乎都不支持CLOCK_MONOTONIC_RAW或CLOCK_MONOTONIC_COARSE。我发现了这个问题。总是错误检查你的* _setclock电话。
POSIX信号量(sem_t)根本不支持任何单调时钟,这是令人愤怒的。如果你需要这个,你将不得不使用条件等待自己滚动。 (作为奖励,这样做可以让您拥有负初始水平的信号量,这可能很方便。)
如果您只是想让同步对象的等待函数永远保持死锁状态,并且您有三秒钟的救助,那么您可以使用CLOCK_MONOTONIC并将其称为一天 - 调整CLOCK_MONOTONIC有效地进行抖动校正,远低于您的精度要求。即使在有缺陷的实现中,CLOCK_MONOTONIC也不会向后跳一小时或类似的东西。同样,相反的是,adjtime这样的事情调整了时钟的频率,使其逐渐超越或落后于其他一些并行运行的时钟。
CLOCK_REALTIME实际上是CLOCK_MONOTONIC,并应用了一些其他校正因子。或者相反。无论如何,它实际上都是一样的。重要的是,如果您的应用程序有可能改变时区(移动车辆,飞机,船舶,巡航导弹,滑旱冰机器人)或遇到行政时钟调整,您绝对不应该使用CLOCK_REALTIME或任何需要它的东西。如果服务器使用夏令时而不是UTC,则同样如此。但是,如果需要,使用UTC的固定服务器可以使用CLOCK_REALTIME来避免粗略的死锁。除非你使用2.6之前的内核并且别无选择,否则请避免这种情况。
CLOCK_MONOTONIC_RAW不是您想要用于时间戳的东西。它尚未进行抖动校正等。它可能适用于DAC和ADC等,但不是您想要用于在人类可识别的时间尺度上记录事件的内容。我们有NTP是有原因的。
希望这有帮助,我当然可以理解挫折感。