【发布时间】:2013-01-21 11:50:53
【问题描述】:
据我所知,CLOCK_MONOTONIC 的 Linux 起点是启动时间。在我目前的工作中,我更喜欢使用单调时钟而不是CLOCK_REALTIME(用于计算),但同时我需要在报告中提供人性化的时间戳(带有年/月/日)。它们可能不是很精确,所以我想在启动时间加入单调计数器。
我可以从哪里使用 api 调用在 linux 系统上获得这个时间?
【问题讨论】:
据我所知,CLOCK_MONOTONIC 的 Linux 起点是启动时间。在我目前的工作中,我更喜欢使用单调时钟而不是CLOCK_REALTIME(用于计算),但同时我需要在报告中提供人性化的时间戳(带有年/月/日)。它们可能不是很精确,所以我想在启动时间加入单调计数器。
我可以从哪里使用 api 调用在 linux 系统上获得这个时间?
【问题讨论】:
假设 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 文件来获取系统启动时间。
【讨论】:
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 进行人类可读的时间。
【讨论】:
CLOCK_MONOTONIC 通常不受系统时间任何调整的影响。例如,如果通过 NTP 调整系统时钟,CLOCK_MONOTONIC 无法知道(也不需要)。
因此,如果您需要人类可读的时间戳,请不要使用 CLOCK_MONOTONIC。
请参阅Difference between CLOCK_REALTIME and CLOCK_MONOTONIC? 进行讨论。
【讨论】:
CLOCK_MONOTONIC。为了解决这个问题,他们添加了CLOCK_MONOTONIC_RAW。