【问题标题】:Starting point for CLOCK_MONOTONICCLOCK_MONOTONIC 的起点
【发布时间】:2013-01-21 11:50:53
【问题描述】:

据我所知,CLOCK_MONOTONIC 的 Linux 起点是启动时间。在我目前的工作中,我更喜欢使用单调时钟而不是CLOCK_REALTIME(用于计算),但同时我需要在报告中提供人性化的时间戳(带有年/月/日)。它们可能不是很精确,所以我想在启动时间加入单调计数器。

我可以从哪里使用 api 调用在 linux 系统上获得这个时间?

【问题讨论】:

    标签: linux real-time


    【解决方案1】:

    假设 Linux 内核在开始跟踪单调时钟的同时启动 uptime 计数器,您可以通过减去 uptime 得出启动时间(相对于 Epoch) 当前时间

    Linux 通过sysinfo 结构以秒为单位提供系统正常运行时间当前时间 可以通过time 函数在符合 POSIX 的库上获取自 Epoch 以来的秒数。

    #include <stddef.h>
    #include <stdio.h>
    #include <time.h>
    #include <sys/sysinfo.h>
    
    int main(void) {
        /* get uptime in seconds */
        struct sysinfo info;
        sysinfo(&info);
    
        /* calculate boot time in seconds since the Epoch */
        const time_t boottime = time(NULL) - info.uptime;
    
        /* get monotonic clock time */
        struct timespec monotime;
        clock_gettime(CLOCK_MONOTONIC, &monotime);
    
        /* calculate current time in seconds since the Epoch */
        time_t curtime = boottime + monotime.tv_sec;
    
        /* get realtime clock time for comparison */
        struct timespec realtime;
        clock_gettime(CLOCK_REALTIME, &realtime);
    
        printf("Boot time = %s", ctime(&boottime));
        printf("Current time = %s", ctime(&curtime));
        printf("Real Time = %s", ctime(&realtime.tv_sec));
    
        return 0;
    }
    

    不幸的是,单调时钟可能与启动时间不完全匹配。当我在我的机器上测试上述代码时,单调时钟与系统正常运行时间相差一秒。但是,只要考虑到相应的偏移量,您仍然可以使用单调时钟。

    可移植性说明:尽管 Linux 可能会返回相对于引导时间的当前单调时间,但 POSIX 机器通常允许从任意任意位置返回当前单调时间——但保持一致-- 时间点(通常是纪元)。


    附带说明,您可能不需要像我那样推导出启动时间。我怀疑有一种方法可以通过 Linux API 获取启动时间,因为有许多 Linux 实用程序以人类可读的格式显示启动时间。例如:

    $ who -b
             system boot  2013-06-21 12:56
    

    我找不到这样的调用,但检查其中一些常用实用程序的源代码可能会发现它们如何确定人类可读的启动时间。

    对于who 实用程序,我怀疑它利用utmp 文件来获取系统启动时间。

    【讨论】:

    • 实际上没有系统调用;至少从 UNIX v6 开始,系统启动时间就记录在 utmp (/var/run/utmp) 中:)
    【解决方案2】:

    http://www.kernel.org/doc/man-pages/online/pages/man2/clock_getres.2.html:

      CLOCK_MONOTONIC
              Clock that cannot be set and represents monotonic time since some
              unspecified starting point.
    

    意味着您可以使用CLOCK_MONOTONIC 进行区间计算和其他事情,但您不能真正将其转换为人类可读的表示。

    此外,您可能想要CLOCK_MONOTONIC_RAW 而不是CLOCK_MONOTONIC

      CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
              Similar  to  CLOCK_MONOTONIC, but provides access to a raw hard‐
              ware-based time that is not subject to NTP adjustments.
    

    继续使用CLOCK_REALTIME 进行人类可读的时间。

    【讨论】:

    • 是的,我知道单调时钟和实时时钟之间的区别。我试图结合这两种方法,因为不想在对象中存储 2 个时间戳 - 单调和实时。我想在工作中使用单调,并以某种方式获取有关起点的信息,然后在客户端添加单调部分。
    • 我试过一次(在 Windows 上,它有糟糕的计时支持)。答案是:不要去那里。如果必须,您可以尝试通过读取两个时钟来估计当前单调到实时的偏移量,但该偏移量可能会在没有警告的情况下发生变化。
    【解决方案3】:

    CLOCK_MONOTONIC 通常不受系统时间任何调整的影响。例如,如果通过 NTP 调整系统时钟,CLOCK_MONOTONIC 无法知道(也不需要)。

    因此,如果您需要人类可读的时间戳,请不要使用 CLOCK_MONOTONIC

    请参阅Difference between CLOCK_REALTIME and CLOCK_MONOTONIC? 进行讨论。

    【讨论】:

    • Linux 不正确CLOCK_MONOTONIC。为了解决这个问题,他们添加了CLOCK_MONOTONIC_RAW
    • CLOCK_MONOTONIC 是单调的,但可以调整。这是通过倾斜计数器来完成的。为了维持时间,一些滴答声将比其他滴答声花费更多/更少的时间。
    猜你喜欢
    • 2012-12-24
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2014-10-24
    • 2022-01-24
    • 2017-03-23
    • 2012-12-25
    相关资源
    最近更新 更多