gettimeofday()为何要同时使用tv_sec与tv_usec成员?
为什么计算
gettimeofday()时间差需要同时用tv_sec和tv_usec? 嗨,我来帮你把这个问题掰明白——这其实是个新手用gettimeofday()时很容易踩的坑,我当初刚接触的时候也犯过一模一样的错误!
直接只算tv_usec差值的问题
你最初的想法只考虑了微秒部分的差值,但忽略了一个关键场景:当计时的结束时间跨过了整秒时,微秒部分会从999999跳回0。举个具体的例子:
- 开始时间
start:tv_sec=100,tv_usec=999999(也就是第100秒的最后1微秒) - 结束时间
end:tv_sec=101,tv_usec=1(也就是第101秒的第1微秒)
如果直接算end.tv_usec - start.tv_usec,得到的是1 - 999999 = -999998,这显然和实际的2微秒(1000000 - 999998)时间差完全不符,更别说转换成纳秒后会得到负数结果了。
正确的计算逻辑
因为struct timeval的tv_sec和tv_usec是组合起来表示完整时间的(tv_usec的范围是0到999999),所以计算差值时必须同时考虑两者:
- 先计算秒数的差值:
sec_diff = end.tv_sec - start.tv_sec - 再计算微秒的差值:
usec_diff = end.tv_usec - start.tv_usec - 如果
usec_diff为负数,说明时间跨过了整秒:- 把
sec_diff减1(因为多算了1秒) - 给
usec_diff加上1000000(补上1秒对应的微秒数)
- 把
- 最后把总时间转换成纳秒:总微秒数 × 1000
代码示例
#include <sys/time.h> #include <stdio.h> int main() { struct timeval start, end; gettimeofday(&start, NULL); // 模拟一段耗时操作(这里用空循环代替) for (long i = 0; i < 1000000; i++); gettimeofday(&end, NULL); long long sec_diff = end.tv_sec - start.tv_sec; long long usec_diff = end.tv_usec - start.tv_usec; // 处理跨秒的情况 if (usec_diff < 0) { sec_diff -= 1; usec_diff += 1000000; } long long total_nsec = (sec_diff * 1000000LL + usec_diff) * 1000LL; printf("耗时:%lld 纳秒\n", total_nsec); return 0; }
补充说明
手册页里其实隐含了这个逻辑:它明确说明tv_usec是“microseconds (0-999999)”,也就是说这个值不会超过1秒,所以时间的完整表示是tv_sec秒加上tv_usec微秒。计算差值时自然要考虑两者的整体变化,而不能只取其中一部分。
内容的提问来源于stack exchange,提问作者Tegernako
相关产品推荐
相关产品推荐

