最可靠方式是两次采样/proc/stat中cpu行jiffies差值归一化计算;c++需注意文件打开检查、行匹配("cpu "开头)、字段动态解析及unsigned long long存储;windows用getsystemtimes并校验api存在性。

Linux下用/proc/stat计算CPU使用率最可靠
直接读/proc/stat是获取用户态+内核态CPU负载比例最轻量、最通用的方式。它不依赖第三方库,也不需要root权限,所有主流Linux发行版都支持。
关键点在于:/proc/stat第一行cpu开头的字段包含user、nice、system、idle、iowait等计数(单位是jiffies),需两次采样做差值再归一化。只读一次得不到“比例”,必须间隔几百毫秒以上再读第二次。
-
user+nice对应用户态时间 -
system对应内核态时间 -
idle+iowait是空闲时间(注意:部分内核版本iowait计入idle,以实际字段数为准) - 总CPU时间 =
user+nice+system+idle+iowait+irq+softirq
C++读取和解析/proc/stat的典型坑
容易出错的地方不是算法,而是文件读取和字符串解析细节:
- 用
std::ifstream读/proc/stat时,必须检查是否打开成功——/proc是虚拟文件系统,路径存在但读失败很常见(比如容器里被挂载限制) - 第一行不一定是
"cpu "开头,也可能是"cpu0 "或"cpu1 ";要找以"cpu "(带空格)开头的行,不是"cpu"前缀匹配 - 字段数量不固定:新内核可能多出
steal、guest等字段,应按实际空格分割后取前8~10个数字,而非硬编码索引 - 数值可能溢出
int,建议统一用unsigned long long存jiffies
Windows上没有/proc/stat,改用GetSystemTimes
Windows下等效方案是GetSystemTimes API,返回三个FILETIME:空闲时间、内核时间(含空闲)、用户时间(不含空闲)。注意:kernel - idle才是纯内核态时间,user就是用户态时间。
- 必须链接
advapi32.lib,否则链接报错LNK2019: unresolved external symbol _GetSystemTimes@12 -
FILETIME是100纳秒单位,需转成毫秒或微秒再做差值计算,别直接当整数减 - 该API在Win XP SP1+可用,但某些精简版系统或WSL1可能不可用,调用前先用
GetProcAddress检查是否存在更稳妥
跨平台封装要注意的兼容性断点
如果写一个跨平台函数get_cpu_usage(),不能简单“Linux走proc,Windows走GetSystemTimes”,因为二者语义不完全对齐:
- Linux的
user包含guest(如果启用),Windows的user不包含虚拟机开销 - Linux
iowait在Windows无直接对应项,通常归入idle更合理 - 采样间隔建议≥500ms:太短会导致浮点精度丢失(jiffies变化太小),太长则实时性差
- 多核场景下,
/proc/stat的cpu行是全核汇总,无需额外聚合;Windows的GetSystemTimes也是全局值,不用遍历逻辑处理器
真正麻烦的是容器环境——/proc/stat看到的是宿主机值,而cgroup限制的CPU quota可能让进程实际使用率远低于此。这时候得配合读/sys/fs/cgroup/cpuacct/cpuacct.usage_percpu或/sys/fs/cgroup/cpu/cpu.stat,但那就不是“系统级”而是“进程组级”了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











