/proc 和 /sys 是内核暴露信息到用户态的两大文件系统——一个历史悠久但混乱,一个设计严谨但有时过于繁琐。
一、先看图
flowchart TD
KERN[内核数据] --> PROCFS[/proc<br/>进程 + 系统信息]
KERN --> SYSFS[/sys<br/>设备 + 子系统]
PROCFS --> PID[/proc/PID/<br/>进程信息]
PROCFS --> SYS_P[/proc/sys/<br/>sysctl]
PROCFS --> MISC[/proc/meminfo<br/>/proc/stat 等]
SYSFS --> CLASS[/sys/class/<br/>设备分类]
SYSFS --> BUS[/sys/bus/<br/>总线]
SYSFS --> FS_S[/sys/fs/<br/>文件系统]
classDef proc fill:#f0883e22,stroke:#f0883e,color:#adbac7;
classDef sys fill:#388bfd22,stroke:#388bfd,color:#adbac7;
class PROCFS,PID,SYS_P,MISC proc
class SYSFS,CLASS,BUS,FS_S sys
二、procfs 设计
2.1 历史
Unix V8(1985)引入 /proc → 最初只有进程信息 → Linux 不断扩展 → 变成”什么都往里塞”。
2.2 常用 /proc/PID 文件
| 文件 | 内容 |
|---|---|
| status | 进程状态、内存、UID/GID |
| maps | 内存映射 |
| fd/ | 打开的文件描述符 |
| cmdline | 命令行参数 |
| stat | 调度统计(格式紧凑) |
| io | I/O 统计 |
| cgroup | cgroup 成员 |
2.3 系统级
cat /proc/meminfo # 内存信息
cat /proc/stat # CPU 统计
cat /proc/loadavg # 负载
cat /proc/interrupts # 中断计数
cat /proc/slabinfo # slab 分配器三、sysfs 设计
3.1 原则
- 每个文件一个值(one value per file)
- 层次结构反映设备拓扑
- 属性由内核子系统注册
3.2 常用路径
/sys/class/net/eth0/speed # 网卡速度
/sys/block/sda/queue/scheduler # I/O 调度器
/sys/devices/system/cpu/cpu0/ # CPU 信息
/sys/fs/cgroup/ # cgroup3.3 kobject
sysfs 的每个目录对应一个 kobject:
struct kobject {
const char *name;
struct kset *kset;
struct kobj_type *ktype;
struct kernfs_node *sd;
// ...
};四、/proc/sys(sysctl)
sysctl -a # 列出所有
sysctl vm.swappiness # 读取
sysctl -w vm.swappiness=10 # 写入对应 /proc/sys/ 目录 → 每个文件是一个 sysctl
参数。
五、pid namespace
# 容器内
cat /proc/1/status # 看到的是容器内的 PID 1
cat /proc/self/status # NSpid 字段显示多级 PIDpid namespace 影响 /proc 看到的进程 → 容器内只能看到自己 namespace 的进程。
六、/proc 的陷阱
6.1 格式不一致
cat /proc/meminfo # "Key: Value kB" 格式
cat /proc/stat # 空格分隔数字
cat /proc/PID/stat # 括号包围的进程名可能含空格6.2 竞态
cat /proc/PID/maps # 进程可能在读取过程中退出读 /proc 不是原子操作 → 长文件可能不一致。
6.3 容器中的误导
/proc/meminfo 在容器中显示宿主机内存 →
应用可能误判可用内存。
解决:LXCFS 或
/sys/fs/cgroup/memory.max。
七、cgroupfs
/sys/fs/cgroup/ # cgroup v2 统一层次
/sys/fs/cgroup/memory.max # 内存限制
/sys/fs/cgroup/cpu.max # CPU 限制cgroup v2 通过 sysfs 风格接口暴露 → 每文件一值。
八、debugfs 与 tracefs
/sys/kernel/debug/ # debugfs(非稳定 ABI)
/sys/kernel/debug/tracing/ # tracefs(非稳定 ABI)仅供调试 → 格式随时可能变化。
九、观察
# 进程详情
cat /proc/self/status
cat /proc/self/maps
ls -la /proc/self/fd/
# 系统概览
cat /proc/meminfo | head -10
cat /proc/stat | head -5
# sysfs 设备
ls /sys/class/net/
cat /sys/block/sda/queue/scheduler
# 检查是否在容器中
cat /proc/1/cgroup十、小结
- /proc 历史悠久 → 混合了进程信息和系统信息
- /sys 设计严谨 → 每文件一值、层次结构
- /proc/sys = sysctl 接口
- pid namespace 影响 /proc 可见性
- 容器中 /proc 可能误导 → 用 cgroup 接口
参考文献
Documentation/filesystems/proc.rstDocumentation/admin-guide/sysfs-rules.rstDocumentation/filesystems/sysfs.rstman 5 proc
工具
cat /proc/...sysctl/sys/...
上一篇:内核日志 下一篇:POSIX capabilities
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】稳定与不稳定 ABI
sysctl/sysfs/tracefs 哪些能依赖?syscall 反而最稳定。本文讲 Documentation/ABI 框架、sysfs 规则、debugfs/tracefs 非承诺、Linus 的 never break userspace 规则与例外。
EEVDF 调度器:Linux 6.6 为什么换掉了 CFS
Linux 6.6 用 EEVDF 取代了 CFS 的 SCHED_NORMAL 选取逻辑。从 1995 年原始论文的 lag、eligibility、virtual deadline,到 commit 147f3ef 只重写 placement/pick/preempt,再到本机内核 6.6 上读 sched/debug 把每个任务的 vruntime、eligible 标志、deadline 一一对上 vd=ve+r/w,外加 nice 带宽与 base_slice 抢占两组实测,讲清换的是哪一块、延迟敏感任务凭什么先跑。
【操作系统百科】Windows 内核与 Linux 的关键差异
NT Executive/Kernel/HAL 分层、Object Manager 与 handle、IRP 驱动栈、IOCP 完成端口 vs epoll/io_uring、EPROCESS/KTHREAD vs task_struct、Registry vs 文件配置,以及 WSL2 为何选择 Hyper-V 轻量 VM。
【操作系统百科】实时 OS 巡礼
硬实时与软实时的可调度性边界、VxWorks/QNX/Zephyr 机制对照、Linux PREEMPT_RT 与主线合入、DO-178C/ISO 26262 认证语境,以及选型决策树。