【问题标题】:CLOCK_MONOTONIC Max valueCLOCK_MONOTONIC 最大值
【发布时间】:2011-07-01 06:29:43
【问题描述】:

clock_gettime() 何时会使用 CLOCK_MONOTONIC 返回一个较小的值,因为它已达到最大值?我指的不是那些被描述为错误的小扭曲,而是计数器重置之类的东西。

是时间测量的,还是与滴答的绝对数量有关?

我必须实现一个计时器(1 或 2 秒间隔),而且我不需要那么精确。但是该应用程序可能会运行几个小时而无需重新启动。 (我估计最多 1 天)。

我不想保证我不会犯任何可能导致它停止通信的错误。

timerfd 是否已经解决了这个问题?

【问题讨论】:

    标签: c linux time


    【解决方案1】:

    由于 struct timespec 使用 time_t 值来表示秒,因此可以覆盖的完整范围至少为 68 年。鉴于 CLOCK_MONOTONIC 的定义是从某个任意点开始,理论上 clock_gettime 可以随时溢出。实际上,如果您的应用程序运行了几十年,您只需要担心这一点。但是,如果您偏执,请创建一个包装函数,该函数会大声抱怨并在发生计时器回绕时终止应用程序。

    【讨论】:

    • 感谢您的回复。我已经运行了一些测试,并且似乎在我的盒子(linux)中,单调时钟实际上是在启动时间(或非常接近它)开始的。这对我来说是个好消息,因为它似乎不太可能超出。
    • 我仍然不确定这被定义为来自 base 的 timespec。根据我读过的文档,它连接到时钟的滴答声,所以应该有这些滴答声的绝对计数器。根据系统的分辨率,这可能比您提到的几十年快得多。任何人都可以支持或反驳这种思路吗?我正在进行一项测试,目前(约 4 小时)未检测到异常行为。
    【解决方案2】:

    CLOCK_MONOTONIC,正如“单调”名称所暗示的那样,永远不会回到过去,它总是在增长。如果用户或其他进程(如 NTP)更改机器上的“挂钟”,则不会更改。 CLOCK_MONOTONIC 是在计时器中使用的正确时间刻度。它最终可能会翻身,但如果您小心操作,即使是这样也可以干净利落地处理。内部定时器使用相同类型的变量。

    例如,如果时钟回绕,以下代码将在前夜正常工作。 注意:kDelayInterval 必须小于环绕周期(这通常不是问题)。

    结构 timespec current_time; 结构 timespec last_update = {0,0}; . . clock_gettime(CLOCK_MONOTONIC, &current_time); if((current_time.tv_sec - last_update.tv_sec) > kDelayInterval) { . . . clock_gettime(CLOCK_MONOTONIC, &last_update); }

    【讨论】:

    • 我所做的测试表明它不会在 23 小时后翻转(在我正在处理的 arm 处理器上),这对我来说已经足够了。我在测试中设置了保护措施,如果 current.tv_sec 小于 inical.tvs_sec,我重置了计时器。我可以承受错过一个 cicle,所以应该这样做。谢谢你的回答。
    • 只有一条评论。实际上,我认为您的代码不起作用,但如果我错了,请纠正我。如果时钟翻转,current_time.tv_sec 小于 last_update.tvsec。所以 current_time - last_update 将是负数,它将在很长一段时间内小于 kDelay 间隔,就在时钟再次翻转之前(假设它以相同的值翻转)。这是我真正想避免的那种情况。
    • 做减法然后比较的好处是翻转处理得很好。 (否定结果会以与翻转相同的方式环绕)。如果时钟变量 (tv_sec) 未签名,则翻转将得到很好的处理。如果时钟变量已签名,您可能会遇到问题。
    • 如果 tv_sec 已签名,那么这一切都取决于翻转后 clock_gettime 返回的内容。如果 MAX_POSSITIVE 之后的下一个数字是 MIN_NEGATIVE 它将正常工作,但是如果 MAX_POSSITIVE 之后的下一个数字是 -1 则它将无法正常工作。您可能需要考虑系统的正常运行时间、tv_sec 的类型和 clock_gettime 的实现,但作为一种通用的可移植方式,这可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 2012-12-24
    • 2013-01-21
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多