linux下需用sysconf(_sc_clk_tck)获取clk_tck,读/proc/[pid]/stat第14、15字段(utime+stime)差值除以clk_tck得进程cpu时间,再除以/proc/stat中cpu行前4字段增量换算的系统总cpu时间,乘以100得利用率;windows下用getprocesstimes()与getsystemtimes()配合,注意filetime转换和权限问题。

Linux下用/proc/[pid]/stat读取时间片并计算CPU利用率
直接读/proc/[pid]/stat第14、15、16、17字段(utime、stime、cutime、cstime)能得到进程用户态+内核态总CPU时间(单位:时钟滴答CLK_TCK)。但注意:这些值是累计值,必须两次采样做差才能算出区间CPU使用率。
关键点:
-
CLK_TCK通常为100,但不能硬编码——需用sysconf(_SC_CLK_TCK)获取 - 第14字段是
utime(用户态时间),第15是stime(内核态时间),第16/17是子进程的对应时间;单进程监控一般只加前两个 - 字段顺序易错:第1个是pid,第2个是comm(括号包围),所以真正数值从第14个开始数(空格分隔,跳过括号)
- 读取时进程可能已退出,
open()或stat()失败要检查返回值
两次采样间隔与系统总CPU时间的同步问题
CPU利用率不是“进程时间 / 采样间隔”,而是“进程消耗的CPU时间 / 系统在该时间段内所有CPU核心可提供的总时间”。例如:双核机器上1秒内最多提供2秒CPU时间。
所以分母要用/proc/stat中cpu行的前4个数(user、nice、system、idle)之和的差值,再换算成真实时间:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 每次读
/proc/stat取cpu行,累加前4个字段得total_jiffies - 两次采样得
delta_total_jiffies,再除以sysconf(_SC_CLK_TCK)转为秒 - 分子是进程
utime + stime的增量,同样要除以CLK_TCK - 最终公式:
(delta_proc_time / delta_total_jiffies) * 100.0(百分比)
Windows下用GetProcessTimes()配合GetSystemTimes()
Windows没有/proc,得靠WinAPI。核心是两组函数配合:
-
GetProcessTimes()返回进程的CreateTime、ExitTime、KernelTime、UserTime(单位:100ns) -
GetSystemTimes()(Win8+)或通过QueryPerformanceCounter()+GetTickCount64()估算系统总时间(旧系统需降级处理) - 注意:
KernelTime和UserTime是64位FILETIME,需用ULARGE_INTEGER转换,否则高位截断 - 若目标进程无权限(如系统进程),
OpenProcess()会失败,需用PROCESS_QUERY_LIMITED_INFORMATION而非全权限
常见错误与性能陷阱
实际写的时候,最容易栽在三个地方:
- 采样间隔太短(/proc/[pid]/stat更新有延迟,且
CLK_TCK=100意味着最小分辨率为10ms,短于它差值常为0 - 没处理进程生命周期:第二次采样时进程已退出,
/proc/[pid]/stat不存在,导致open()失败后仍继续解析,结果不可信 - 忽略多核归一化:直接用
(delta_utime + delta_stime) / interval_sec * 100,会得出远超100%的值(比如四核机器上算出320%),这不是bug,是没除系统总可用时间 - Linux下
/proc/[pid]/stat可能因进程名含空格被字段错位——必须按空格split后跳过comm字段(它被括号包着,且可能跨字段),稳妥做法是用std::regex或手动找第一个')'位置再往后数
真实场景里,utime/stime的精度足够,但别指望它能反映毫秒级抖动;如果要做高频监控(如每10ms一次),得切到eBPF或perf_event,那又是另一套机制了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










