linux下读取/proc/self/io的read_bytes字段可获进程自启动以来从块设备实际读取的字节数,需用sscanf解析且检查返回值,注意沙盒环境限制及内核版本差异。

Linux下读取/proc/pid/io中的read_bytes字段
Linux内核在/proc/[pid]/io中暴露了进程I/O统计,其中read_bytes行表示该进程自启动以来从块设备(含磁盘)实际读取的字节数(不包括缓存命中)。这是最直接、无需特权的方式。
- 注意
read_bytes是累计值,不是瞬时速率;单位是字节,数值为十进制字符串 - 需用
getpid()获取当前PID,拼接路径:/proc/self/io(推荐)或/proc/12345/io - 文件需按行解析,匹配以
read_bytes:开头的行,跳过空格后提取数字部分 - 若进程被沙盒化(如snap、flatpak)或容器中/proc被挂载为只读,可能读取失败,应检查
errno == EACCES或ENOENT
解析/proc/self/io时容易忽略的格式细节
/proc/self/io每行格式为key: value,但value前可能有多个空格或制表符,且末尾无换行符。直接std::getline + std::string::find易出错。
Windows 命令行编码与兼容规范。涵盖 GBK/UTF-8 编码、PowerShell/pwsh 互操作、Python/Node.js、Git 配置及代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。
- 建议用
std::istringstream逐行分割,或用sscanf(line.c_str(), "read_bytes: %ld", &bytes)更鲁棒 - 某些内核版本(如4.15+)对
read_bytes的定义更严格:仅统计发往块设备的读,page cache命中不计入;而rchar包含所有read()系统调用字节数(含缓存) - 务必检查返回值:若
sscanf返回值不为1,说明该行格式不符,应跳过
跨平台兼容性问题与替代方案
Windows没有等效的/proc接口,GetProcessIoCounters返回的ReadBytes字段在不同系统版本含义不一——Windows 10 1809+才保证为真实磁盘读取量,旧版仅含缓存读。
- 纯C++标准库无法跨平台获取此指标;必须条件编译:
#ifdef __linux__走/proc/self/io,#ifdef _WIN32调用GetProcessIoCounters - macOS无直接对应API;
task_info仅提供bytes_read,但它是虚拟内存层统计,不区分磁盘/缓存 - 若需跨平台近似值,可结合
statvfs监控文件系统整体读取趋势,但无法精确到单个进程
权限与稳定性风险
读取/proc/self/io本身不需要root权限,但该文件在进程生命周期内可能短暂不可读(如内核正在更新计数器),导致open()返回ENOENT或read()返回0。
- 不要假设文件一定存在;每次读取都应检查
open()返回值及read()字节数 - 避免高频轮询(如/proc会增加内核开销;生产环境建议缓存结果并按秒级更新
- 注意:容器环境(Docker/Podman)默认挂载
/proc为ro,需加--privileged或显式挂载/proc:/proc:rshared才能读取
read_bytes的解释差异和容器环境下的挂载限制——得先确认你的目标环境是否真能拿到这个数。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










