一、概述
Linux 系统中,一切皆为文件的理念提供了最高级的抽象,开发者只需要使用一套 API 就可以操作 Linux 系统中的绝大部分资源。
而在整个 Linux 目录树中, 有一个最重要的 (虚拟) 目录: /proc,在系统启动时创建,在系统关闭时销毁。
内核态通过简洁的文件内容 API 形式,将系统的大部分状态在用户态充分暴露出来,这样用户/程序直接读取 /proc 目录下面的相关文件,就可以获取到对应的系统/进程等状态和数据,真可谓大道至简。

总之,想要知道当前系统中运行了哪些进程、每个进程都打开了哪些文件、进程的 CPU、内存等使用情况如何、每个进程启动了几个线程、当前有哪些 TCP/UDP 连接、每个网卡收发的字节数等等,都可以在 /proc 目录中找到答案。
BTW, 直接读取 /proc 目录下面的文件内容,也是很多 Linux 常用命令和开源系统监控组件的实现原理。
本文主要从开发者使用 Linux 系统的角度,着重分析一下 /proc 目录下可以获取到的四类信息:
系统硬件/设备网络进程
二、系统相关
1. 内核版本/编译器/编译时间
复制
$ cat /proc/version
Linux version 6.6.87+ (builder@f33bfd62b873) (Chromium OS 17.0_pre498229-r33 clang version 17.0.0 (/var/cache/chromeos-cache/distfiles/egit-src/external/github.com/llvm/llvm-project 14f0776550b5a49e1c42f49a00213f7f3fa047bf), LLD 17.0.0) #1 SMP PREEMPT_DYNAMIC Sat May 3 09:33:57 UTC 20251.2.3.
可以看到,输出的信息远比 uname 命令获取到内容要详细。
复制
$ uname -a
Linux cs-100667547897-default 6.6.87+ #1 SMP PREEMPT_DYNAMIC Sat May 3 09:33:57 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux1.2.3.
2. 系统负载
输出系统最近 1/5/15 分钟的平均负载。
复制
$ cat /proc/loadavg
0.03 0.01 0.00 1/300 12721.2.3.
对比 uptime 命令的输出:
复制
$ uptime
14:12:36 up 7:44, 0 user, load average: 0.03, 0.01, 0.001.2.3.
3. 硬中断
输出系统中的硬件中断情况,按照 CPU 进行分组。
复制
$ cat /proc/interrupts
# output
CPU0 CPU1
0: 269 0 IO-APIC 0-edge timer
1: 0 9 IO-APIC 1-edge i8042
4: 0 2067 IO-APIC 4-edge ttyS0
6: 70 0 IO-APIC 6-edge
8: 0 0 IO-APIC 8-edge rtc0
9: 0 0 IO-APIC 9-fasteoi acpi
10: 0 16876 IO-APIC 10-fasteoi virtio2
...1.2.3.4.5.6.7.8.9.10.11.12.13.14.
4. 软中断
输出系统中的硬件中断情况,按照 CPU 进行分组。
复制
$ cat /proc/softirqs
# output
CPU0 CPU1
HI: 0 0
TIMER: 98735 84868
NET_TX: 2 4
NET_RX: 18737 28301
BLOCK: 0 29051
IRQ_POLL: 0 0
TASKLET: 44 30
SCHED: 200114 198635
HRTIMER: 0 0
RCU: 57886 617361.2.3.4.5.6.7.8.9.10.11.12.13.14.15.
每个 CPU 都对应一个软中断内核线程运行状况,所以使用下面的命令,也可以获取到 CPU 软中断运行情况。
复制
$ ps aux | grep softirq1.
5. 内核参数
通过读写文件来动态调整内核参数,例如在TCP 100 万长连接的参数调优[2] 一文中,就涉及到很多 /proc/sys 目录下面相关文件的参数修改,限于篇幅,这里不再赘述了。
三、硬件相关
1. CPU
输出机器上所有 (逻辑) CPU 型号、核心数、频率等详细信息。
复制
$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
...
processor : 1
vendor_id : GenuineIntel
cpu family : 6
...1.2.3.4.5.6.7.8.9.10.11.12.13.
可以在此基础上计算出 (逻辑) CPU 的数量。
复制
$ cat /proc/cpuinfo | grep processor | wc -l1.
常用的 Linux 命令中的 lscpu,输出的源数据就来自 /proc/meminfo 文件。
2. 内存
输出机器上物理内存、交换分区、缓存等信息。
复制
$ cat /proc/meminfo
MemTotal: 8138112 kB
MemFree: 6372192 kB
MemAvailable: 7426484 kB
Buffers: 74336 kB
Cached: 1177368 kB
SwapCached: 0 kB
...1.2.3.4.5.6.7.8.9.10.
常用的 Linux 命令中的 free 和 top,输出的源数据就来自 /proc/meminfo 文件。
复制
$ free
total used free shared buff/cache available
Mem: 8138112 711636 6372192 1108 1301156 7426476
Swap: 0 0 01.2.3.4.5.
四、网络相关
1. 网卡数据统计
输出网卡接口的统计信息,例如发送数据量、接收数据量、错误数量。
复制
$ cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 31272563 12256 0 0 0 0 0 0 31272563 12256 0 0 0 0 0 0
eth0: 6263742 24376 0 0 0 0 0 0 18041254 18792 0 0 0 0 0 0
docker0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 01.2.3.4.5.6.7.
常用的 ifconfig 命令,数据源就是 /proc/net/dev 文件。
复制
$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1460
...
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1460
...
RX packets 24328 bytes 6256091 (6.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 18758 bytes 18034626 (18.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
...
RX packets 12216 bytes 31268081 (31.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12216 bytes 31268081 (31.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 01.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.
2. 网络连接状态和对列
输出 TCP/UDP 网络连接,及其对应的端口号和状态等信息。
复制
$ cat /proc/net/tcp
$ cat /proc/net/udp1.2.3.

常用的 Linux 网络命令中, netstat 和 ss 命令就是对 /proc/net/tcp、/proc/net/udp、/proc/net/raw 等文件内容进行了二次加工,具体的过程这里就不展开了 🙂 。
下面是使用 netstat 和 ss 命令的输出结果:


3. ARP 表
ARP 表存储着当前局域网中各主机的 IP 地址到 MAC 地址的映射关系。
复制
$ cat /proc/net/arp
IP address HW type Flags HW address Mask Device
10.88.0.1 0x1 0x2 12:a5:12:b7:15:70 * eth01.2.3.4.
下面是对等的 arp 命令。
复制
$ arp -an
? (10.88.0.1) at 12:a5:12:b7:15:70 [ether] on eth01.2.3.
五、进程相关
每个进程都有一个进程 ID (数字) pid,所以和进程相关的信息都在目录 /proc/{pid} 下面。
例如下面展示了 root 用户打开的相关进程:
复制
...
dr-xr-xr-x 9 root root 0 May 19 23:19 207/
dr-xr-xr-x 9 root root 0 May 19 23:19 25/
dr-xr-xr-x 9 root root 0 May 19 23:19 26/
dr-xr-xr-x 9 root root 0 May 19 23:19 264/
dr-xr-xr-x 9 root root 0 May 19 23:20 270/
dr-xr-xr-x 9 root root 0 May 19 23:19 271/
dr-xr-xr-x 9 root root 0 May 19 23:20 275/
dr-xr-xr-x 9 root root 0 May 19 23:19 285/
dr-xr-xr-x 9 root root 0 May 19 23:19 296/
dr-xr-xr-x 9 root root 0 May 19 23:20 467/
...1.2.3.4.5.6.7.8.9.10.11.12.13.14.
下文的示例中,统一以笔者机器上运行的 dockerd 进程为例,进行代码和命令输出结果演示。
复制
root 207 1 0 23:19 ? 00:00:00 /usr/bin/dockerd -p /var/run/docker.pid --mtu=14601.
演示 docker 进程 pid = 207
1. 启动参数
输出进程的启动命令及其参数。
复制
$ sudo cat /proc/207/cmdline
/usr/bin/dockerd-p/var/run/docker.pid--mtu=14601.2.3.
2. 进程状态
输出进程的 pid、ppid、内存使用等信息。
复制
$ sudo cat /proc/207/status
# output
Name: dockerd
Umask: 0022
State: S (sleeping)
Tgid: 207
Ngid: 0
Pid: 207
PPid: 1
...
Threads: 10
...
Cpus_allowed: 3
Cpus_allowed_list: 0-1
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
...1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
3. 函数调用栈
输出进程当前正在执行的的函数调用栈。
复制
$ sudo cat /proc/207/stack
# output
[<0>] futex_wait_queue+0xdd/0x130
[<0>] futex_wait+0x179/0x300
[<0>] do_futex+0x18f/0x1e0
[<0>] __se_sys_futex+0x152/0x1d0
[<0>] do_syscall_64+0x46/0xb0
[<0>] entry_SYSCALL_64_after_hwframe+0x78/0xe21.2.3.4.5.6.7.8.9.10.
4. 线程状态
输出进程
复制
$ sudo ls -l /proc/207/task/
# output
total 0
dr-xr-xr-x 7 root root 0 May 20 13:43 206
dr-xr-xr-x 7 root root 0 May 20 13:44 212
dr-xr-xr-x 7 root root 0 May 20 13:44 213
dr-xr-xr-x 7 root root 0 May 20 13:44 214
dr-xr-xr-x 7 root root 0 May 20 13:44 215
dr-xr-xr-x 7 root root 0 May 20 13:44 221
dr-xr-xr-x 7 root root 0 May 20 13:44 229
dr-xr-xr-x 7 root root 0 May 20 13:44 249
dr-xr-xr-x 7 root root 0 May 20 13:44 263
dr-xr-xr-x 7 root root 0 May 20 13:44 2751.2.3.4.5.6.7.8.9.10.11.12.13.14.15.
下面是使用 pstree 命令输出的线程结果。

5. 打开文件
输出 dockerd 进程打开的所有文件句柄 (fd)。
复制
$ sudo ls -l /proc/207/fd/1.

6. 内存映射
输出进程内存映射区域(例如堆、共享库),smaps 细化到每个区域的 RSS 和脏页统计,用于内存泄漏分析 (具体的分析方法,感兴趣的读者可以自行搜索)。
复制
$ sudo cat /proc/212/maps1.

复制
$ sudo cat /proc/212/smaps1.
会逐行输入类似如下的内存映射信息:

Linux 命令中的 pmap 的数据源就是 maps 和 smaps 文件。

7. OOM
Linux 内核 OOM killer 会在内存不足时,选择性地杀掉用户进程。
它的运行规则简单来说就是,OOM killer 会为每个用户进程设置一个权重值,这个权重值越高,被 kill 的概率越高,反之概率越低。
每个进程的权重值存放在 /proc/{pid}/oom_adj 中,大多数进程的默认权重值都是 0。
复制
$ sudo cat /proc/207/oom_adj1.
8. 网络连接

进程网络相关的文件都在 /proc/{pid}/net 目录下面,可以根据不同的协议类型查看对应的文件,输出结果和 /proc/net/ 下面的文件基本类似,限于篇幅,这里就不再赘述了。
六、小结
