clock_gettime 和 CLOCK_REALTIME 有什么问题?

What is wrong with clock_gettime with CLOCK_REALTIME?

考虑以下代码:

struct timespec ts;
uint64_t start_time;
uint64_t stop_time;

if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
    abort();
}
 
start_time = ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
 
/* some computation... */
 
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
    abort();
}
 
stop_time = ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
 
printf("%" PRIu64 "\n", (stop_time - start_time + 500000000) / 1000000000);

在绝大多数情况下,代码都按我预期的方式工作,即打印计算所用的秒数。 但是,很少会出现一种异常情况。 该程序报告秒数,如 18446743875、18446743877、18446743962 等。 我认为这个数字大致匹配 264 纳秒(~584 年)。 所以我怀疑 ts.tv_nsec 有时等于 −1.

所以我的问题是: 我的代码有什么问题? 添加 264 纳秒的位置和原因是什么?

我没有发现您的代码有任何问题。我怀疑您的 OS 偶尔会为 CLOCK_REALTIME 提供异常值 — 虽然我很惊讶,但我无法想象它可能是什么。

我建议像这样重写您的代码:

struct timespec start_ts, stop_ts;
uint64_t start_time;
uint64_t stop_time;

if (clock_gettime(CLOCK_REALTIME, &start_ts) != 0) {
    abort();
}
 
start_time = start_ts.tv_sec * UINT64_C(1000000000) + start_ts.tv_nsec;
 
/* some computation... */
 
if (clock_gettime(CLOCK_REALTIME, &stop_ts) != 0) {
    abort();
}
 
stop_time = stop_ts.tv_sec * UINT64_C(1000000000) + stop_ts.tv_nsec;

uint64_t elapsed = (stop_time - start_time + 500000000) / 1000000000;
printf("%" PRIu64 "\n", elapsed);

if(elapsed > 365 * 86400 * UINT64_C(1000000000)) {
    printf("ANOMALY:\n");
    printf("start_ts = %lu %lu\n", start_ts.tv_sec, start_ts.tv_nsec);
    printf("stop_ts = %lu %lu\n", stop_ts.tv_sec, stop_ts.tv_nsec);
}

然后,if/when它再次发生,您将有更多信息可以继续。