为什么 time() 报告的时间有时会比 C 代码中 timespec_get() 的秒部分晚 1 秒?
Why is the time reported by time() sometimes 1 second behind the seconds component of timespec_get() in C code?
以下代码片段:
struct timespec ts;
for (int x = 0; x < 100000000; x++) {
timespec_get(&ts, TIME_UTC);
long cTime = (long) time(NULL);
if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) {
printf("cTime: %ld\n", cTime);
printf("ts.tv_sec: %ld\n", ts.tv_sec);
printf("ts.tv_nsec: %ld\n", ts.tv_nsec);
}
}
产生这个输出:
...
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2527419
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2534036
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2540359
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2547039
...
为什么 cTime
和 ts.tv_sec
之间存在差异?请注意,如果条件更改为 ts.tv_nsec >= 3000000
,则不会出现此问题。该问题依赖于小于 3000000 的纳秒。
原因是您(隐含地)使用了不同的系统时钟。 timespec_get()
使用高分辨率 系统级实时时钟,而time()
使用粗 实时时钟。
尝试使用
clock_gettime(CLOCK_REALTIME_COARSE, &ts);
而不是你的 timespec_get()
,那么差异应该消失。
编辑:
这个可以在Linux Kernel Source, vclock_gettime.c
中看到
确实,这里的问题有点微妙。 CLOCK_REALTIME_COARSE
和 CLOCK_REALTIME
使用的结构成员的秒部分包含相同的值,但 纳秒部分 不同;使用 CLOCK_REALTIME
它可以大于 1000000000
(即一秒)。在这种情况下,它是固定在调用上的:
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
CLOCK_REALTIME_COARSE
和 time()
均未执行此更正。这解释了 CLOCK_REALTIME
和 time()
之间的区别。
以下代码片段:
struct timespec ts;
for (int x = 0; x < 100000000; x++) {
timespec_get(&ts, TIME_UTC);
long cTime = (long) time(NULL);
if (cTime != ts.tv_sec && ts.tv_nsec < 3000000) {
printf("cTime: %ld\n", cTime);
printf("ts.tv_sec: %ld\n", ts.tv_sec);
printf("ts.tv_nsec: %ld\n", ts.tv_nsec);
}
}
产生这个输出:
...
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2527419
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2534036
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2540359
cTime: 1579268059
ts.tv_sec: 1579268060
ts.tv_nsec: 2547039
...
为什么 cTime
和 ts.tv_sec
之间存在差异?请注意,如果条件更改为 ts.tv_nsec >= 3000000
,则不会出现此问题。该问题依赖于小于 3000000 的纳秒。
原因是您(隐含地)使用了不同的系统时钟。 timespec_get()
使用高分辨率 系统级实时时钟,而time()
使用粗 实时时钟。
尝试使用
clock_gettime(CLOCK_REALTIME_COARSE, &ts);
而不是你的 timespec_get()
,那么差异应该消失。
编辑:
这个可以在Linux Kernel Source, vclock_gettime.c
中看到确实,这里的问题有点微妙。 CLOCK_REALTIME_COARSE
和 CLOCK_REALTIME
使用的结构成员的秒部分包含相同的值,但 纳秒部分 不同;使用 CLOCK_REALTIME
它可以大于 1000000000
(即一秒)。在这种情况下,它是固定在调用上的:
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
CLOCK_REALTIME_COARSE
和 time()
均未执行此更正。这解释了 CLOCK_REALTIME
和 time()
之间的区别。