Linux用/proc/stat两次采样计算CPU负载率,Windows用GetSystemTimes或PDH;需sleep≥200ms、用unsigned long long解析、校验返回值,避免溢出、休眠干扰和权限问题。

Linux 下直接读 /proc/stat 是最轻量、最可靠的方式;Windows 必须用 GetSystemTimes(Vista+)或 PdhCollectQueryData,别碰 getloadavg 或 WMI——它们不是 CPU 使用率。
Linux:两次读 /proc/stat 的 cpu 行算全局负载
第一行以 cpu 开头(注意末尾有空格,不是 cpu0)记录的是所有核心的累计 jiffies。字段顺序固定:user、nice、system、idle、iowait、irq、softirq、steal……
- 必须两次采样,间隔 ≥ 200ms:用
std::this_thread::sleep_for(std::chrono::milliseconds(250)),别连续读两次 - 所有字段必须用
unsigned long long解析,否则高负载机器几小时就溢出回绕 - 总时间 = 所有字段和;空闲时间 =
idle+iowait(严格定义下 iowait 属于等待 I/O 的空闲) - 负载率 =
(total_delta - idle_delta - iowait_delta) / total_delta,不是1.0 - idle_delta / total_delta - 若两次采样间系统休眠,
total_delta突增 >1e9 jiffies/250ms,整组数据应丢弃
Windows:用 GetSystemTimes 算全局,用 PDH 算单核
GetSystemTimes 返回三个 FILETIME:空闲、内核(含空闲)、用户。它只在 Vista 及以后可用,需链接 advapi32.lib,且调用前必须检查函数地址是否有效:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetSystemTimes")获取地址,返回nullptr则 fallback -
FILETIME是 100ns 单位,必须转成uint64_t(推荐ULARGE_INTEGER),不能直接结构体相减 - 总活跃时间 = (内核时间 − 空闲时间)+ 用户时间;负载率 = 活跃时间 / 总时间
- 单核数据 Windows 不提供原生接口,只能用 PDH API 查询
\Processor(0)\% Processor Time等计数器 - PDH 首次
PdhCollectQueryData常返回PDH_INVALID_DATA,需 sleep 100ms 后再调一次
跨平台封装时最容易忽略的三个点
Linux 和 Windows 的底层机制完全不同:一个是单调递增计数器差值,一个是性能快照。强行抽象会踩坑:
立即学习“C++免费学习笔记(深入)”;
- 别在同一个函数里连续读两次
/proc/stat就算负载——中间没 sleep,差值恒为 0 或极小 - 别用
std::thread::hardware_concurrency()推算核心数来循环读cpu0~cpuN——容器或节能模式下部分核可能不在线,应逐行读文件匹配^cpu[0-9]+ - 别把
GetSystemTimes当作跨平台 fallback:它在非管理员权限下调用会失败(ERROR_ACCESS_DENIED),而 Linux 版本连 root 都不需要
真正难的不是读数据,而是让两次采样“稳”:间隔太短,idle 几乎不变;间隔太长,响应滞后;中间被调度打断,差值失真。这些细节不写死 sleep、不校验类型、不检查返回值,跑几天就出负数或 1000%。

















