直接读/proc/stat和/proc/meminfo即可,用std::ifstream逐行解析,注意jiffies差值计算CPU使用率、kB单位为十进制、优先用MemAvailable并处理内核版本差异。
直接读
和
就行,别碰 syscall 或第三方库
Linux 的
是内核吐出的纯文本接口,C++ 读它跟读普通文件完全一样——用
或
即可。没人需要 syscall、
或
,那些是给系统工具(如
)封装用的,你写监控脚本或轻量采集器,直接 parse 文本最稳。
常见错误是试图用
检查
是否存在来“判断进程存活”,结果发现刚 fork 出来的进程还没来得及注册进
,
就返回失败——这不是 bug,是
的天然竞态。真要查进程,要么重试几次,要么改用
。
里第一行
后面的数字是各 CPU 模式下的 jiffies(非毫秒!),需两次采样做差再换算
的值单位统一是
(注意不是 KB),
和
是关键字段
别用
无脑读整行再
——有些发行版(如 RHEL 8+)默认关闭
,只留
,必须兼容
读
文件时,必须检查
而非只看 EOF
文件不是磁盘文件,读取过程可能被内核中断(比如 CPU 热插拔导致
行数突变),
容易静默失败:流状态变成
,但你没检查就继续
,变量值还是旧的,结果 CPU 使用率卡在 0%。
每次
后立刻检查
,不能只靠
推荐用
+
逐行读,再用
(或手写
)匹配,避免
把空格当分隔符吃掉字段
读
时,某行可能是
,中间多个空格,别用
直接读三个变量,会错位;先
切割键值,再
转数字
计算 CPU 使用率必须采样两次,且间隔 ≥100ms
单次读
只能拿到累计 jiffies,没法算使用率。核心逻辑是:记录两次时间戳和对应的
、
、
、
值,求差值后按比例折算——但很多人忽略两个硬约束:
立即学习
“
C++免费学习笔记(深入)
”;
C知道
CSDN推出的一款AI技术问答工具
下载
两次采样间隔太短(如 10ms),jiffies 差值可能为 0(尤其空闲机器),导致除零或结果跳变
别用
算耗时然后除以 1e9 得秒数——jiffies 是内核滴答,和 wall-clock 不严格线性对应;只要两次间隔 ≥100ms,误差可接受
公式里分母是所有模式 jiffies 总和的差值(
),不是只用
;漏掉
会导致使用率虚高
示例片段:
内存单位陷阱:
的
是千字节,不是 KiB
文档写的是 “kB”,实际值是十进制千字节(1000 字节),不是二进制 KiB(1024 字节)。虽然误差仅 2.4%,但如果你拿这个值去和
算页数,或者和
返回的字节数对比,就会对不上。
是物理内存总大小(含保留区),
是内核估算的、可立即分配给用户进程的内存,比
更准,优先用它
某些嵌入式 kernel(如 Android 的 vendor kernel)可能不提供
,此时 fallback 到
,但要注意
是 slab 中可回收部分,不是所有
都能动
别把
当唯一依据——OOM killer 触发前,
可能还有几百 MB,但具体到某个进程,
仍会失败,因为内存碎片或 cgroup 限额已满
真实环境里,
解析最难的不是语法,是应对内核版本差异和容器化带来的字段漂移——比如
下,
的
可能被截断,
里看不到 cgroup mount 信息。这些没法靠“标准做法”解决,只能根据目标环境实测校验。
/proc/stat/proc/meminfo/procstd::ifstreamfopenlibprocpssysfsutilstopstat()/proc/pid/status/procstat()/prockill(pid, 0)/proc/statcpu/proc/meminfokBMemTotal:MemAvailable:std::getlinefind("MemFree:") MemFreeMemAvailablestd::ifstream/procfailbit/proc/proc/statstd::ifstreamfailbit>>operator>>if (!ifs) { /* handle error */ }eof()std::string linestd::getline()absl::StartsWith(line, "cpu ") line.substr(0, 4) == "cpu ">>/proc/meminfoMemAvailable: 123456 kB>>find_first_of(':')stoll/proc/statusersystemidleiowaitstd::chrono::steady_clock::now()user + system + idle + iowait + ...user + systemidlelong long total_jiffies_diff = (user2 + nice2 + system2 + idle2 + iowait2) - (user1 + nice1 + system1 + idle1 + iowait1);
double cpu_usage = 100.0 * (total_jiffies_diff - (idle2 - idle1)) / total_jiffies_diff;/proc/meminfokBsysconf(_SC_PAGESIZE)getrusage()MemTotal:MemAvailable:MemFree + Buffers + CachedMemAvailableMemFree + Buffers + Cached - SReclaimableSReclaimableCached/proc/meminfoMemAvailablemalloc()/proccgroups v2/proc/1/statusCapEff:/proc/mounts