最可靠方式是两次采样/proc/stat中cpu行各字段差值计算:负载率 = (user+nice+system+irq+softirq+iowait) / (所有非idle时间之和 + idle),间隔≥100ms,分母含idle,分子不含。

Linux下用/proc/stat算总CPU负载率最可靠
直接读/proc/stat是Linux获取CPU总体负载的底层方式,比调用库函数更可控、无依赖。第一行cpu(不含后缀数字)记录所有核心的累计时间戳,包含user、nice、system、idle、iowait、irq、softirq等字段。负载率不是“当前瞬时值”,必须两次采样做差值再计算:
- 间隔至少100ms,太短会导致
idle几乎不变,结果失真 - 分母是所有非-idle时间之和(即
user + nice + system + irq + softirq + iowait),分子是这个和本身,负载率 = 分子 / (分子 +idle) - 注意
/proc/stat中idle包含idle和iowait(旧内核)或单独列出(新内核),以实际字段顺序为准,别硬编码索引
Linux多核明细要遍历cpu0、cpu1…行
/proc/stat里每行以cpuN开头的就是第N个逻辑核的数据。不能只看cpu行就认为是平均值——它只是累加和。要获取各核负载,得逐行解析cpu0到cpu(N-1)(N = sysconf(_SC_NPROCESSORS_ONLN)):
- 每轮采样需保存每个
cpuN行的全部7+字段值,下次再读再做差 - 单核负载率公式和总负载一致,但只用该行数据,不跨核混用
- 某些虚拟化环境(如WSL2)可能只暴露部分逻辑核,
sysconf返回数 ≠/proc/stat中cpuN最大编号,建议以文件实际行为准
Windows上必须用PdhAddCounter + PdhCollectQueryData
Windows没有类似/proc的伪文件系统,得走PDH(Performance Data Helper)API。关键不是查单个计数器,而是绑定\Processor(_Total)\% Processor Time(总负载)和\Processor(0)\% Processor Time等(单核明细):
- 必须先调
PdhOpenQuery,再对每个计数器路径调PdhAddCounter,最后PdhCollectQueryData触发采集 - 首次调用
PdhCollectQueryData常返回PDH_INVALID_DATA,需sleep 100ms后再调一次才有效 - 计数器路径中的括号是字面量,
_Total不能写成Total,(0)不能漏括号,否则PdhAddCounter返回PDH_CSTATUS_INVALID_COUNTER_PATH
跨平台封装要注意采样时机和精度损失
如果写跨平台工具,别试图用同一套逻辑抽象Linux/Windows。二者本质不同:Linux靠时间戳差值,Windows靠性能计数器快照。常见坑包括:
立即学习“C++免费学习笔记(深入)”;
- 把两次
/proc/stat读取放在同一个函数里连续执行,中间没sleep → 差值为0或极小,负载率恒为0 - Windows下反复
PdhOpenQuery/PdhCloseQuery,导致句柄泄漏或查询失败;应复用query对象 - 用
float存时间差再除法,32位浮点在长时间运行后精度不足,建议全程用int64_t存jiffies或100ns单位,最后转double算百分比
多核明细输出本身不难,难的是让两次采样真正反映“过去100ms发生了什么”。时间窗口没对齐,所有数字都是假的。


















