You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),所以计算差值时必须同时考虑两者:

  1. 先计算秒数的差值:sec_diff = end.tv_sec - start.tv_sec
  2. 再计算微秒的差值:usec_diff = end.tv_usec - start.tv_usec
  3. 如果usec_diff为负数,说明时间跨过了整秒:
    • 把sec_diff减1(因为多算了1秒)
    • 给usec_diff加上1000000(补上1秒对应的微秒数)
  4. 最后把总时间转换成纳秒:总微秒数 × 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 06:58:10