Linux的proc文件系统揭秘

本文详细介绍了Linux的proc文件系统,这是一个虚拟的文件系统,用于显示关于进程和其他系统信息。文章解释了如何通过proc文件系统获取进程信息,如环境变量、文件描述符和内存映射,并展示了如何读取系统信息,如CPU信息、内存使用情况和平均负载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux的proc文件系统(procfs)的全称是process information pseudo-filesystem(进程信息伪文件系统)。它是一个虚拟的文件系统,通常在系统启动时被自动挂载到/proc目录,以一个多级的目录/文件的方式显示关于进程和其它的系统信息。

proc文件系统中的绝大多数文件是只读的,但也有一些是可写的(例如/proc/sys)。

proc文件系统提供了从用户空间通往内核空间的一个入口,通过读取其中的文件来动态地获得内核的状态。很多Linux系统命令,比如lsmod、ps,都是通过直接访问proc文件系统来获得数据。此外还可以通过修改某些文件的内容来改变内核参数。

与一般的文件系统存储在磁盘上不同,procfs存在于内存中。因而你会发现/proc目录下的文件大小都是0(除了kcore、mtrr、self);并且对文件的修改也不会被持久化(比如通过sysctl修改内核参数在重启后会失效)。

进程信息

Linux为系统中运行的每一个进程在/proc下创建了一个子目录——/proc/PID,PID为进程ID。
在这里插入图片描述这些子目录包含了所对应的进程的信息,包括:

  • /proc/PID/cmdline 最初启动进程的命令,比如在下面的例子中,7588是一个java进程
# cat /proc/7588/cmdline 
java -Djava.security.egd=file:/dev/./urandom -jar demo-ui-0.20.1-SNAPSHOT.jar
  • /proc/PID/cwd 指向进程当前工作目录的符号链接(symbolic link)
# ls -lt /proc/7588/cwd 
lrwxrwxrwx 1 root root 0 Jan 19 06:33 /proc/7588/cwd -> /app # 7588进程的工作目录是/app
  • /proc/PID/environ 进程的环境变量
  • /proc/PID/exe 指向进程可执行文件的符号链接(symbolic link),例如:
# ls -lh /proc/7588/exe
lrwxrwxrwx 1 root root 0 Dec 10 17:32 /proc/7588/exe -> /usr/lib/jvm/java-8-oracle/bin/java
  • /proc/PID/fd 这个目录包含了指向进程中每一个打开的文件描述符的符号链接(链接名就是文件描述符的编号),例如:
# ls -ltr /proc/7588/fd
total 0
lr-x------ 1 root root 64 Jan 18 14:36 9 -> /dev/urandom
lr-x------ 1 root root 64 Jan 18 14:36 8 -> /usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar
l-wx------ 1 root root 64 Jan 18 14:36 7 -> /root/.mofa/logs/_logs_/default/local-demo-ui-0.log
l-wx------ 1 root root 64 Jan 18 14:36 6 -> /root/.mofa/logs/_logs_/default/local-demo-ui-0.error
lrwx------ 1 root root 64 Jan 18 14:36 59 -> anon_inode:[eventpoll]
l-wx------ 1 root root 64 Jan 18 14:36 58 -> pipe:[48487]
lr-x------ 1 root root 64 Jan 18 14:36 57 -> pipe:[48487]
lrwx------ 1 root root 64 Jan 18 14:36 56 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Jan 18 14:36 50 -> socket:[48484]
...
  • /proc/PID/fdinfo 在这个目录中,每一个打开的文件描述符有一个对应的文件,内容包括对应文件的一些信息,比如:
# cat /proc/7588/fdinfo/30
pos:	0        # 文件offset
flags:	04001    # 文件flags
mnt_id:	10       # 包含这个文件的挂载点ID
  • /proc/PID/maps 这个文件包含了当前映射的内存区域。
    +
  • /proc/PID/mem 进程的内存
  • /proc/PID/root 指向这个进程根目录的符号链接,通常就是“/”。例如:
# ls -lt /proc/7588/root
lrwxrwxrwx 1 root root 0 Jan 18 09:38 root -> /
  • /proc/PID/status 进程的状态信息,包括:
# cat /proc/7588/status
Name:	java                       # 进程运行的指令
State:	S (sleeping)               # 进程当前的状态,"R (running)", "S (sleeping)", "D (disk sleep)", "T (stopped)", "T(tracing stop)", "Z (zombie)",  "X (dead)"
Tgid:	7588                       # 线程组ID,一般就是进程ID
Ngid:	0                          # NUMA group ID
Pid:	7588                       # 进程ID
PPid:	7565                       # 父进程ID 
TracerPid:	0                      # PID of process tracing this process (0 if not being traced).
Uid:	0	0	0	0
Gid:	0	0	0	0
FDSize:	256
Groups:	0 1 2 3 4 6 10 11 20 26 27 
NStgid:	7588	1
NSpid:	7588	1
NSpgid:	7588	1
NSsid:	7588	1
VmPeak:	 5637656 kB
VmSize:	 5637656 kB             # 系统为进程分配的虚拟内存的大小 ,有关进程内存,详情参考:https://blog.csdn.net/sinat_26058371/article/details/86536213          
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	 1029820 kB             # RSS的峰值大小
VmRSS:	 1029820 kB             # RSS大小
VmData:	 5581264 kB             # 数据大小
VmStk:	     132 kB             # 栈大小
VmExe:	       4 kB             # text segment大小
VmLib:	   18240 kB             # 共享库代码大小
VmPTE:	    2320 kB
VmPMD:	      36 kB
VmSwap:	       0 kB             # 交换分区的大小
HugetlbPages:	       0 kB
Threads:	41                  # 进程中线程的数量
SigQ:	0/31353
SigPnd:	0000000000000000
ShdPnd:	0000000000000000
SigBlk:	0000000000000000
SigIgn:	0000000000000000
SigCgt:	2000000181005ccf
CapInh:	00000000a80425fb
CapPrm:	00000000a80425fb
CapEff:	00000000a80425fb
CapBnd:	00000000a80425fb
CapAmb:	0000000000000000
Seccomp:	0
Cpus_allowed:	f                # 这个进程能够运行的CPU掩码,这台机器的CPU有4个核心,f(1111)表示这个进程可以在所有核心上运行
Cpus_allowed_list:	0-3          # 这个进程能够运行在那些cpu上,cpu的id是一个数组,通常范围是0 ~ cpu核数-1(这里就是0、1、2、3)
Mems_allowed:	00000000,00000001  # 这个进程能够访问的内存节点掩码(和NUMA的group id一致)
Mems_allowed_list:	0              # 这个进程能够访问的内存节点(和NUMA的group id一致)
voluntary_ctxt_switches:	56
nonvoluntary_ctxt_switches:	5
  • /proc/PID/task 这个目录中,进程中的每一个线程都有一个对应的子目录,子目录名就是线程ID,子目录中的文件结构与/proc/PID目录中的一致。例如:
# ls /proc/7588/task/7642
attr    children    comm    environ  fdinfo   limits    mem        net        oom_adj        pagemap      root       sessionid  stack  status   wchan
auxv    clear_refs  cpuset  exe      gid_map  loginuid  mountinfo  ns         oom_score      personality  sched      setgroups  stat   syscall
cgroup  cmdline     cwd     fd       io       maps      mounts     numa_maps  oom_score_adj  projid_map   schedstat  smaps      statm  uid_map
  • /proc/PID/ns 包含进程所属的各个namespaces的文件描述符。例如:
# ls /proc/7588/ns
total 0
lrwxrwxrwx 1 root root 0 Feb 27 10:26 uts -> uts:[4026531838]
lrwxrwxrwx 1 root root 0 Feb 27 10:26 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Feb 27 10:26 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Feb 27 10:26 net -> net:[4026531968]
lrwxrwxrwx 1 root root 0 Feb 27 10:26 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Feb 27 10:26 ipc -> ipc:[4026531839]
  • /proc/self 指向程序自己的进程目录。比较拗口,举个例子,比如两个程序的进程ID分别是123和456,这两个程序都访问/proc/self目录,那么它们实际访问的目录分别为/proc/123和/proc/456。

进程相关的命令

Linux中的查询进程最常用命令ps就是通过读取proc文件系统来获得进程信息的。
在了解了/proc/PID中各个文件的含义后,我们也可以通过直接访问文件的方式来获得进程信息。例如

$ readlink /proc/$(pgrep -n java)/exe  # 找到最后运行的Java程序的java可执行文件的路径
/usr/lib/jvm/java-8-oracle/bin/java
$ cat /proc/7588/status | grep VmSize # 获得7588号进程所使用的内存
VmRSS:	 2947192 kB 

其它系统信息

起初procfs只提供进程(process)相关的信息,这也是它的名字的由来。但之后Linux又向里加入了一些与进程无关的其它一些系统信息。在2.6内核中,很多信息被挪到了另一个文件系统——sys(在之后一篇文章中会单独介绍)。

proc文件系统提供的主要系统信息包括:

  • /proc/cpuinfo 主机的cpu信息。下面是在一台4核主机上的/proc/cpuinfo的内容:
# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 79
model name      : Intel(R) Xeon(R) CPU E5-26xx v4
stepping        : 1
microcode       : 0x1
cpu MHz         : 2394.454
cache size      : 4096 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch bmi1 avx2 bmi2 rdseed adx xsaveopt
bugs            :
bogomips        : 4788.90
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor       : 1
...

processor       : 2
...

processor       : 3
...
  • /proc/meminfo 系统的内存使用信息,包含物理内存和swap分区。free命令就是读取这个文件。例如:
# cat /proc/meminfo 
MemTotal:        8043944 kB
MemFree:         1834160 kB
MemAvailable:    4329456 kB
Buffers:          491388 kB
Cached:          2091380 kB
SwapCached:            0 kB
Active:          4260852 kB
Inactive:        1370900 kB
Active(anon):    3055416 kB
Inactive(anon):    34128 kB
Active(file):    1205436 kB
Inactive(file):  1336772 kB
Unevictable:        3660 kB
Mlocked:            3660 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:              1228 kB
Writeback:             0 kB
AnonPages:       3052880 kB
Mapped:           520800 kB
Shmem:             38140 kB
Slab:             463060 kB
SReclaimable:     257024 kB
SUnreclaim:       206036 kB
KernelStack:       20208 kB
PageTables:        17232 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     4021972 kB
Committed_AS:   11174476 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
HardwareCorrupted:     0 kB
AnonHugePages:   1994752 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      264184 kB
DirectMap2M:     8124416 kB
  • /proc/loadavg 系统的平均负载水平
# cat /proc/loadavg
5.57 5.01 4.91 5/1250 27822

前三个值分别是1、5、15分钟的负载平均值;第四项“5/1250”分别表示当前有5个可运行的进/线程,当前在系统中一共存在1250个进/线程;最后一个值是系统最近创建的进程的PID。

  • /proc/modules 当前所加载的内核模块,lsmod命令读取该文件。
  • /proc/sys 这个目录包括很多的文件,一个文件对应一个内核参数。每一个文件看上去都是一个普通的文本文件,里面的内容只有一个值(通常就是一个整数),代表参数的值。内核参数的名称都是分段式的,之间用“.”隔开,每一段对应了一级子目录(和java的package机制类似)。比如内核参数net.core.somaxconn对应的文件是“/proc/sys/net/core/somaxconn”。可以通过修改这些文件的内容来设置内核参数,比如:
# echo 65535 > /proc/sys/net/core/somaxconn
  • /proc/net 网络相关的信息。内容很多,常用的文件包括:
  1. /proc/net/arp ARP缓存
# cat /proc/net/arp    # arp缓存
IP address       HW type     Flags       HW address            Mask     Device
10.201.54.252    0x1         0x2         0a:58:0a:c9:36:fc     *        cbr0
10.201.54.246    0x1         0x2         0a:58:0a:c9:36:f6     *        cbr0
10.201.54.248    0x1         0x2         0a:58:0a:c9:36:f8     *        cbr0
10.201.54.130    0x1         0x2         0a:58:0a:c9:36:82     *        cbr0
  1. /proc/net/dev 网络设备状态信息
# cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
veth38482784:       0       0    0    0    0     0          0         0      504      12    0    0    0     0       0          0
veth5972cf8d: 24146809  293505    0    0    0     0          0         0 147188022  386266    0    0    0     0       0          0
veth148b56dc: 17633628  195860    0    0    0     0          0         0 70001394  197908    0    0    0     0       0          0
 bond1: 596288963157 832107276    0   13    0     0          0   2656255 1678252721434 1276200925    0    0    0     
  1. /proc/net/route 路由信息,route指令读取这个文件
# cat /proc/net/route  # 路由信息
Iface	Destination	Gateway 	Flags	RefCnt	Use	Metric	Mask		MTU	Window	IRTT                                                       
bond1	00000000	0136C90A	0003	0	    0	0	    00000000	0	0	0                                                                              
bond1	0036C90A	00000000	0001	0	    0	0	    00FFFFFF	0	0	0                                                                              
cbr0	8036C90A	00000000	0001	0	    0	0	    80FFFFFF	0	0	0                                                                               
docker0	0000FE0A	00000000	0001	0	    0	0	    00F0FFFF	0	0	0                                                                            
bond1	00004064	0136C90A	0003	0	    0	0	    0000C0FF	0	0	0                                                                              
bond1	0000FEA9	00000000	0001	0	    0	1006	0000FFFF	0	0	          
  1. /proc/net/nf_conntrack 当前的网络链接,netstat指令输出的就是这个文件的内容。
# cat /proc/net/nf_conntrack
ipv4     2 tcp      6 95 TIME_WAIT src=127.0.0.1 dst=127.0.0.1 sport=35974 dport=60001 src=127.0.0.1 dst=127.0.0.1 sport=60001 dport=35974 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 13 TIME_WAIT src=10.201.54.129 dst=10.201.54.252 sport=42086 dport=8080 src=10.201.54.252 dst=10.201.54.129 sport=8080 dport=42086 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 86377 ESTABLISHED src=127.0.0.1 dst=127.0.0.1 sport=60752 dport=60001 src=127.0.0.1 dst=127.0.0.1 sport=60001 dport=60752 [ASSURED] mark=0 zone=0 use=2
...
  • /proc/uptime 系统的运行时间
# cat /proc/uptime
3373642.34 7841089.28

3373642.34表示系统已经运行了3373642.34秒(39天左右);7841089.28代表系统空闲的时间(单位秒,大约78天)。之所以空闲的时间比运行的时间还要多,是因为每个cpu核心的空闲时间是单独计算的。上面这台4核主机的空闲率大致为:7841089.28 / 3373642.34 /4 = 58%

  • /proc/stat 内核/系统的各种统计数据
    在这里插入图片描述
  • /proc/version 内核版本
# cat /proc/version
Linux version 4.4.0-104-generic (buildd@lgw01-amd64-022) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) ) #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值