直接读取 /proc/loadavg 是最简单可靠的方式,Linux 内核实时写入 1/5/15 分钟负载值,C++ 程序用 std::ifstream 和 std::stod 解析前三列浮点数,需处理文件不可见、权限等错误,并注意 load average 表示等待 CPU 或不可中断状态的进程数,非 CPU 使用率。

直接读取 /proc/loadavg 是最简单可靠的方式
Linux 内核把当前系统的 1/5/15 分钟 load average 实时写在 /proc/loadavg 文件里,C++ 程序只需打开并解析该文件——不需要调用系统 API、不依赖第三方库、也不用处理 getloadavg() 的 POSIX 兼容性问题。
这个文件格式固定:前三列是三个浮点数(如 0.42 0.38 0.35),后面两列是运行/总进程数和最近使用的 PID,我们只关心前三个值。
- 用
std::ifstream读取,比fopen更符合 C++ 风格,且自动处理换行和空格分隔 - 务必检查文件是否成功打开,
/proc在容器或 chroot 环境下可能不可见 - 建议用
std::stod()而非scanf或atof,避免 C 风格字符串生命周期问题
getloadavg() 在 glibc 中可用但有陷阱
POSIX 定义了 getloadavg() 函数,glibc 实现也确实可用,但它返回的是“自上次调用以来的平均值缓存”,不是实时刷新的;而且它要求传入至少 1 个元素的 double 数组,长度必须 ≥3 才能拿到全部三值。
- 头文件必须包含
<sys/loadavg.h>,不是<unistd.h> - 返回值是成功写入的元素个数,若返回 -1 表示不可用(比如某些嵌入式 libc 不实现它)
- 在 musl libc(Alpine Linux 默认)中,
getloadavg()直接返回 -1,此时 fallback 到读/proc/loadavg是必须的 - 即使成功,它的精度和更新频率与
/proc/loadavg完全一致,没额外优势
解析时要注意字段顺序和浮点精度
/proc/loadavg 每行固定 5 个字段,但不同内核版本字段数不变,只是最后两个字段含义略有差异(比如第 4 列在较新内核中是“运行中进程数/总进程数”)。我们只取前三个字段,但不能假设它们一定以空格分隔——实际是任意空白符(空格、制表符、换行)。
立即学习“C++免费学习笔记(深入)”;
- 用
std::istringstream+>>提取 double 最安全,它自动跳过所有空白 - 不要用
std::string::find_first_of(" \t")手动切分,容易漏掉连续空格或制表符 - load 值本身是 double 类型,但通常只保留两位小数显示;内部计算无需四舍五入,直接用原值参与逻辑判断
- 极端情况下(如系统刚启动),第一个值可能为
0.00,这是正常现象,不是错误
封装成函数时需考虑线程安全和 errno 处理
如果多个线程并发调用读取 load average 的函数,/proc/loadavg 是只读文件,本身无竞争;但 std::ifstream 对象不是线程安全的,应避免复用同一实例。
- 每次调用都新建
std::ifstream,开销极小(/proc是内存伪文件) - 失败时不要只靠
ifs.fail(),还要检查errno(比如ENOENT表示 /proc 不可用,EACCES表示权限不足) - 返回值建议用
std::optional<std::array<double, 3>>,比裸指针或 bool+out 参数更清晰表达“可能无值”语义 - 别忘了
std::array的索引对应:[0] 是 1 分钟,[1] 是 5 分钟,[2] 是 15 分钟——这个顺序容易记反
真正麻烦的不是读取,而是理解 load average 的含义:它反映的是“等待 CPU 或不可中断状态的平均进程数”,不是 CPU 使用率。很多监控脚本误把它当 CPU 百分比用,结果告警阈值设错。这点比技术实现更值得多看一眼。


















