gettimeofday()与times()的统计结果存在较大差异
这种times()统计的累计CPU时间远小于gettimeofday()获取的经过时间的情况,本质是CPU时间和**墙上时钟时间(wall-clock time)**的定义差异导致的:前者只统计程序实际占用CPU执行指令的时间,后者是从任务开始到结束的绝对时间跨度。结合你的场景,最可能的原因有这些:
程序长期处于等待状态:如果你的应用在分析的这段逻辑中,频繁进行I/O操作(比如磁盘文件读写、数据库查询、网络请求)、等待同步锁释放,或者等待系统信号/其他进程的响应,那么CPU会被操作系统调度去处理其他任务,这段等待时间不会被
times()计入,但会被gettimeofday()算入总耗时。比如如果你的应用在调用外部API或者处理大量磁盘IO,就会出现CPU时间远小于实际经过时间的情况。系统CPU资源被抢占:如果应用运行的服务器负载很高(比如同时运行多个CPU密集型任务),你的程序会频繁处于就绪队列中等待CPU调度,这段等待时间同样不会被
times()统计,但会体现在gettimeofday()的结果里。你可以观察进程的CPU使用率,你的场景中17700/51000≈35%,符合CPU使用率长期低于100%的特征,大概率是这个原因。times()的统计范围遗漏:需要确认你调用times()时是否正确覆盖了所有相关的执行单元。比如如果你的应用使用了多线程架构,部分系统的times()默认只统计主线程的CPU时间,而没有包含其他工作线程的耗时;或者如果应用启动了子进程,但你没有将子进程的CPU时间纳入统计(不过这种情况通常会让CPU时间更小,需要结合实际代码排查)。
排查建议
你可以用这些工具进一步定位问题:
- 用
top或pidstat实时观察进程的CPU使用率、等待IO的时间占比; - 用
strace跟踪进程的系统调用,查看是否存在大量等待型调用(如select、poll、read/write); - 检查
times()的调用逻辑,确认是否正确统计了所有子进程/线程的CPU时间。
内容的提问来源于stack exchange,提问作者Paul Floyd

