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它再次发生,您将有更多信息可以继续。
考虑以下代码:
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它再次发生,您将有更多信息可以继续。