深度剖析Linux进程的内部机制:一探/proc/pid的奥秘

简介: 深度剖析Linux进程的内部机制:一探/proc/pid的奥秘

I. 介绍/proc目录

/proc目录的作用

/proc目录是Linux系统中的一个虚拟文件系统,它提供了许多有关系统硬件和进程的信息。/proc目录中的每个文件都是一个虚拟文件,它们实时反映了系统当前的状态和信息,可以通过读取这些文件来获取有关系统的各种信息。/proc目录是一个非常重要的目录,对于系统管理、调试和性能优化等方面都有很大的帮助。


/proc目录结构

/proc目录结构是一个树形结构,包含了许多子目录和文件,它们的名称和内容都反映了系统的不同方面。例如,/proc/cpuinfo文件包含了处理器的信息,/proc/meminfo文件包含了内存使用情况的信息,/proc/net目录包含了网络协议的信息,/proc/sys目录包含了系统内核的配置参数等等。通过读取这些文件,可以及时了解系统的状态和运行情况,方便进行系统管理和调试。

总之,/proc目录是Linux系统中的一个非常重要的目录,它提供了丰富的系统信息,可以通过读取其中的文件来了解系统的状态和运行情况。在系统管理、调试和性能优化等方面,/proc目录都有着重要的作用。


II. /proc/pid目录

/proc/pid目录的作用

/proc/pid目录是Linux系统中的一个虚拟文件系统目录,它包含了有关进程的信息,每个进程都有一个对应的/proc/pid目录。通过读取/proc/pid目录中的文件,可以及时了解进程的状态和运行情况,方便进行进程管理和调试。

/proc/pid目录结构

/proc/pid目录结构是一个树形结构,包含了许多子目录和文件,它们的名称和内容都反映了进程的不同方面。

/proc/pid目录是Linux系统中非常重要的一个目录,它提供了丰富的进程信息,可以通过读取其中的文件来了解进程的状态和运行情况。在进程管理、调试和性能优化等方面,/proc/pid目录都有着重要的作用。


/proc/pid子目录 记录了进程的相关信息

  • cmdline文件:包含了进程启动时使用的完整命令行参数。
  • cwd符号链接:包含了当前进程工作目录的一个符号链接。
  • environ文件:包含了进程环境变量的列表。
  • exe符号链接:包含了正在进程中运行的程序的符号链接。
  • fd子目录:包含了进程打开的每个文件的符号链接,每个符号链接的名称为文件描述符。
  • maps文件:包含了进程的内存映射信息,包括代码段、数据段、堆和栈等。
  • mem文件:包含了进程在内存中的内容,可以读取和写入该文件来读写进程的内存。
  • root符号链接:包含了进程根目录的符号链接。
  • stat文件:包含了进程的状态信息,如进程ID、父进程ID、状态、CPU使用情况等。
  • statm文件:包含了进程的内存使用信息,如内存大小、共享内存大小、代码大小等。

III. 常见的/proc/pid信息

/proc/pid/attr:安全相关的选项

/proc/pid/attr是一个目录,这个目录下的文件的作用是为安全模块提供了API.通过这些文件我们可以读取或者设置一些安全相关的选项.

这个目录目前能够支持SELinux,但是本意是为了能够支持更多的其他的安全模块.****以下将会演示SELinux如何使用这些文件.

PS: 只有内核开启了CONFIG_SECURITY选项,才能够看到这个目录.

  • /proc/pid/attr/current:进程的安全上下文
    在SELinux中,这个文件主要是用于得到当前进程的安全上下文.在2.6.11的内核之前,这个文件不能用来设置安全上下文(写操作是不允许的),因为SELinux限制了进程安全转换为 EXECVE(2) (参考下方的/proc/pid/attr/exec). 从2.6.11之后,SELinux取消了这个限制.如果策略允许,SELinux通过向这个文件写入来支持设置行为,虽然这个操作仅仅只是为了维护老的上下文和新的上下文的隔离.在2.6.28之前,SELinux不允许多线程程序的线程通过这个值来设置安全上下文,因为这样会导致共享内存空间的县城的安全上下文不一致.从2.6.28之后,SELinux取消了这个限制,开始支持多线程的设置方法.但是需要满足一定的条件,新的安全上下文需要绑定在老的上下文上,并且这个绑定关系是设置在策略当中的,同时新的安全上下文是老的安全上下文的一个子集.
  • /proc/pid/attr/exec
    这个文件代表给进程的execve的属性.
    在SELinux中,有时候需要支持role/domain的转换,execve(2)一般都是作为这种转换的首选,因为它提供了对进程的新的安全标签和状态继承的更好的控制.在SELinux中,如果重置了execve(2),那么这个程序就会恢复到execve(2)所设置的状态.
  • /proc/pid/attr/fscreate

这个文件代表进程与文件有关的权限,包括open(2) mkdir(2) symlink(2) mknod(2)

SELinux通过此文件能够保证以一个安全的方式创建文件,所以这里不会存在不安全的访问的风险(在文件创建和文件属性设置).如果重置了execve(2),那么程序也会被重置,包括程序所创建的文件.

  • /proc/pid/attr/keycreate
    如果进程将安全上下文写入此文件,那么所有创建key的行为都会被加载到此上下文中.更多的信息可以参考内核文件 Documentation/security/keys/core.rst(在Linux3.0和Linux4.13中文件是 Documentation/security/keys.txt 在Linux3.0之前是Documentation/keys.txt)
  • /proc/pid/attr/prev

这个文件包含了进程在执行最后一个execve(2)的安全上下文.换句话说,这个文件的内容是/proc/pid/attr/current前一个值

  • /proc/pid/attr/socketcreate

如果一个进程向这个文件写入安全上下文,那么之后所有的sockets的创建行为都会在此进程上下文中;这个文件包含了进程在执行最后一个execve(2)的安全上下文.换句话说,这个文件的内容是/proc/pid/attr/current前一个值

/proc/pid/autogroup:该目录包含了进程的自动分组信息。

参考 sched(7)

/proc/pid/auxv:该文件包含了进程的辅助向量信息。

这个文件包含了在进程执行时,传递给进程的ELF的解释器的信息.这个文件的格式是一个无符号的long类型的ID加上每个entry的一个无符号的long类型,这最后的一个entry包含了两个零。参考 getauxval(3)

/proc/pid/cgroup:该文件包含了进程所在的控制组信息。

参考 cgroups(7)

/proc/pid/clear_refs:该文件用于清除进程使用的匿名内存页的引用计数。

这是一个只写文件,只有进程的owner能够写.只有下面这些值能够被写入:

  1. (Since Linux 2.6.22)对进程所有的相关的页重置所有的PG_Referenced 和ACCESSED/YOUNG位 (在2.6.32之前,任何的非零的值写入到此文件都是有效的)
  2. (Since Linux2.6.32) 对进程所有的匿名页重置所有的PG_Referenced和ACCESSED/YOUNG位
  3. (Since Linux2.6.32)对进程所有的与文件相关的页重置所有的PG_Referenced和ACCESSED/YOUNG位.清除所有的PG_Referenced和ACCESSED/YOUNG提供了一个方法用于测量一个进程是有了多少内存.第一个可以参考的是/proc/[pid]/smaps中的VMAs中的值.当清除了PG_Referenced和ACCESSED/YOUNG 经过一段时间之后,再次测量这个值.
  4. (Since Linux3.11) 清空掉进程所有的页的soft-dirty位.通过向/proc/[pid]/clear_refs清空,就能够知道哪些页是被污染了.
  5. 将peak resident重置为进程当前的resident的大小.

如果向/proc/pid/clear_refs写入其他的任何值,不会有任何的效果;只有当启用了CONFGI_PROC_PAGE_MONITOR的内核选项之,才会出现/proc/pid/clear_refs文件

/proc/pid/cmdline:该文件包含了进程启动时使用的命令行参数。

这个只读文件是包含了进程执行的完整命令.如果此进程是一个僵尸进程,那么次文件没有任何的内容.

/proc/pid/comm:该文件包含了进程的命令名。

此文件记录的是进程命令的comm.在同一个进程中的不同线程的comm可能不同,可以访问/proc/[pid]/task/tid/comm获取进程中的每个线程的comm.通过向/proc/self/task/tid/comm写入就能够修改自己或者其他线程的comm.如果comm超过TASK_COMM_LEN(16)就会被截断.

这个文件的值可以通过 prctl(2) 的PR_SET_NAME和PR_GET_NAME的操作来设置和获取,通过 pthread_setname_np(3) 能够设置线程的comm.

/proc/pid/coredump_filter:该文件包含了进程的转储核心过滤器。

参考 core(5)

/proc/pid/cpuset:该文件包含了进程所在的CPU集合信息。

参考 cpuset(7)

/proc/pid/cwd:该文件是一个符号链接,指向当前进程的工作目录。

这是一个当前的进程的工作目录,可以通过如下的命令查看:

#Method 1:
cd /proc/pid/cwd && /bin/pwd
#Method 2:
/proc/pid/cwd; pwd -P

在多线程的程序中,如果主线程已经退出了,那么cwd的结果就是空.取消或者是读取(readlink(2))这个链接的内容的权限是由ptrace的访问模式PTRACE_MODE_READ_FSCREDS来控制的,参考ptrace(2)

/proc/pid/environ:该文件包含了进程的环境变量列表。

这个文件包含的是当程序使用execve启动程序时的环境变量的值,其中的entries是通过0x0分割的,结尾是可能是null.如果我们需要查询一个指定的进程的环境变量,我们可以采用如下的方法:

cat /proc/pid/environ | tr '\000' '\n'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=commoncollection
LANG=C.UTF-8
JAVA_HOME=/docker-java-home/jre
JAVA_VERSION=8u212
JAVA_DEBIAN_VERSION=8u212-b01-1~deb9u1
HOME=/root

如果执行了execve(2)之后,进程调用了putenv(3)或者是直接修改environ(7) ,那么environ变量的值是无法随之改变的.

更进一步,进程能够通过prctl(2)修改PR_SET_MM_ENV_START的值来修改这个文件所引用的内存位置.读取这个文件的权限是由ptrace(2)的PTRACE_MODE_READ_FSCREDS来控制.

/proc/pid/exe:该文件是一个符号链接,指向当前进程正在执行的可执行文件。

在Linux2.2的内核及其之后,/proc/pid/exe是直接执行的二进制文件的符号链接.这个符号链接能够被取消.尝试打开这个文件就相当与打开了二进制文件,甚至可以通过重新输入/proc/pid/exe重新运行一个对应于pid的二进制文件.在一个多线程的程序中,如果主线程已经退出了,就无法访问这个符号链接.

在Linux2.0及其之前,/proc/pid/exe是指向当前进程执行的二进制文件.采用readlink()读取返回如下的结果: [device]:inode

/proc/pid/fd:该目录包含了当前进程打开的文件描述符列表。

这是一个子目录,包含了当前进程打开的每一个文件.每一个条目都是一个文件描述符,是一个符号链接,指向的是实际打开的地址.0表示标准输入,1表示标准输出,2表示标准错误.在多线程程序中,如果主程序退出了,那么这个文件夹将不能被访问.

程序能够使用文件名作为命令行参数,如果没有提供这样的参数,就不会从标准输入中读取信息也不会将标准输出发送到文件中.但是即使没有提供与文件相关的命令行参数,我们仍然可以使用标准的输出输入.

#例如我们可以通过-i和-o分别指向输入和输出文件.:
$ foobar -i /proc/self/fd/0 -o /proc/self/fd/1 ...
#在某些UNIX或者类似UNIX的系统中,/proc/self/fd/N与/dev/fd/N大致相同.大部分系统提供/dev/stdin,/dev/stdout,/dev/stderr的符号链接,分别只想的是/proc/self/fd中的0,1,2.所以上述的命令也可以写为:
$ foobar -i /dev/stdin -o /dev/stdout ...

/proc/pid/fdinfo:该目录包含了当前进程打开的文件描述符信息。

这是一个子目录,包括了当前进程打开的所有的文件的文件描述符.可以读取每一个文件描述符的内容一获取i信息.如下所示:

$ cat /proc/5040/fdinfo/99
pos: 21718
flags: 0100000
mnt_id: 27
  • pos 是十进制,显示当前文件的偏移量
  • flags是八进制,显示文件的访问模式和文件状态标志.
    该目录中的文件只有进程的所有者才可以读.

/proc/pid/limits:该文件包含了进程的资源限制信息。

该文件显示了每个进程的软中断,硬中断和度量单位.在Linux2.6.35之前,这个文件仅仅只能被进程实际的UID访问.在26.36之后,该文件可以被系统中所有的用户读取.

/proc/pid/maps:该文件包含了进程的内存映射信息。

包含了当前进程映射的内存区域以及他们的访问权限.文件格式如下:

#当您打印该命名管道内容时(例如使用 cat),您将看到该进程地址空间中当前映射到文件中的那部分。自左至右各列为:
#与该映射关联的地址空间,与该映射关联的权限,该映射起始位置的偏移量(从文件开始处算起),保存该映射文件设备的主、从序号(十六进制格式),该文件的 inode 序号,以及该文件的文件名。当设备号为 0 且没有 inode 号或文件名时,它就是一个匿名映射。
address           perms offset   dev  inode  pathname
08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
08056000-08058000 rw-p 0000d000 03:0c 64593 /usr/sbin/gpm
08058000-0805b000 rwxp 00000000 00:00 0
40000000-40013000 r-xp 00000000 03:0c 4165 /lib/ld-2.2.4.so
40013000-40015000 rw-p 00012000 03:0c 4165 /lib/ld-2.2.4.so
4001f000-40135000 r-xp 00000000 03:0c 45494 /lib/libc-2.2.4.so
40135000-4013e000 rw-p 00115000 03:0c 45494 /lib/libc-2.2.4.so
4013e000-40142000 rw-p 00000000 00:00 0
bffff000-c0000000 rwxp 00000000 00:00 0
  • address,表示进程占用的地址.
  • perms, 表示一系列权限.r=read,w=write,x=execute,s=shared,p=private(copy on write)
  • offset, 表示文件偏移量
  • dev:表示设备 (主要设备,次要设备)
  • inode: 表示设备上面的inode编号.如果是0,表示没有索引节点与内存区域关联,就如同BSS段一样.
  • pathname,在Linux2.0之前,没有pathname字段.

/proc/pid/mem:该文件包含了进程在内存中的内容。

该文件可以通过open,read,seek访问进程的内存页.

/proc/pid/mountinfo:该文件包含了进程所挂载的文件系统信息。

这个文件主要是包含了挂载信息.文件内容结构如下:

36 35 98:0  /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
(1)(2)(3)    (4) (5)      (6)        (7)   (8)(9)  (10)                 (11)
  1. mount ID,挂载点的唯一标识
  2. parent ID,当前挂载点的父挂载点的ID
  3. major:minor, files的st_dev的值
  4. root: 文件系统的根挂载点
  5. mount point: 相对于进程根目录的挂载点
  6. mount options: 预挂载选项
  7. options fields: tag:[value]类型的字段
  8. sparator: options fields结束标志
  9. file systemtype: 文件系统的名称,以type[.subtype]的方式命名
  10. mount source: 文件特定信息
  11. super options: 超级块选项

/proc/pid/mounts:该文件包含了进程所挂载的文件系统信息,与mountinfo文件类似。

列出在当前进程挂载空间下所有的已经挂载过的文件.文件的格式通过 fstab 查看.在kernel 2.6.15之后,这个文件是论询式的.在读取文件之后,这个事件会导致select标记这个文件是可读的,并且pool()和epoll_wait()会将此文件标记为遇到了错误.

/proc/pid/mountstas:该文件包含了进程所挂载的文件系统的统计信息。

该文件会列举在当前进程挂载空间下的所有挂载点的详细信息,包括统计信息,配置信息.文件格式如下:

device /dev/sda7 mounted on /home with fstype ext3 [statistics]
( 1 )                       ( 2 )             ( 3 )  ( 4 )
  1. 载的设备名
  2. 挂载点
  3. 文件系统类型
  4. 可选的统计和配置信息.在2.6.26之后,仅NFS文件系统可以到处此字段信息

/proc/pid/ns/:该目录包含了进程的命名空间信息。

这是一个子目录.每一个子目录可以通过 setns 操作.关于更多的操作,参见clone

/proc/pid/ns/ipc:该文件是一个符号链接,指向进程的IPC命名空间。

将文件挂载在其他地方可以使pid指定的进程的IPC命名空间保持活动状态,即使在当前命名空间的所有的进程全部都截止了.打开次文件就会返回文件句柄.只要文件保持打开状态,那么IPC的命名空间就可以保持活动状态.文件描述符可以通过 setns 传递.

/proc/pid/ns/net:该文件是一个符号链接,指向进程的网络命名空间。

将文件挂载在其他地方可以使pid指定的进程的网络命名空间保持活动状态,即使在当前命名空间的所有的进程全部都截止了.打开次文件就会返回文件句柄.只要文件保持打开状态,那么网络的命名空间就可以保持活动状态.文件描述符可以通过 setns 传递.

/proc/pid/ns/uts:该文件是一个符号链接,指向进程的UTS命名空间。

将文件挂载在其他地方可以使pid指定的进程的UTS 命名空间保持活动状态,即使在当前命名空间的所有的进程全部都截止了.打开次文件就会返回文件句柄.只要文件保持打开状态,那么UTS命名空间就可以保持活动状态.文件描述符可以通过 setns 传递

/proc/pid/numa_maps:该文件包含了进程的NUMA内存映射信息。

参见 numa

/proc/pid/oom_adj:该文件包含了进程的OOM(Out of Memory)值,即内存不足时该进程被杀死的优先级。

这个方法用于决定在出现OOM的情况下,哪个进程被杀掉.内核使用该值对进程的oom_score的值进行设定,oom_score的有效取值区间是-17至15.-17将会完全杀死这个进程.正数会增加进程当oom时被杀掉的可能性,负数会减小进程被oom杀掉的可能性.

该文件的默认值是0.新进程会继承其父进程的oom_adj设置.只有具有CAP_SYS_RESOURCE权限的进程才能够更新此文件.

在Linux2.6.36,推荐使用/proc/[pid]/oom_score_adj.

/proc/pid/oom_score:该文件包含了进程的OOM得分,即OOM杀死该进程的优先级。

该文件显示了如果内核出现oom情况时决定杀死该进程时的分数.分数越高意味着进程越容易被杀掉.

/proc/pid/oom_adj_score:该文件包含了进程的OOM值和OOM得分。

这个文件用于调整在内存不足时应该杀掉哪个进程的分数判断.

/proc/pid/root:该文件是一个符号链接,指向进程的根目录。

该值可以用于 chroot 预先设定进程的根文件系统. 这个文件指向当前进程的根目录.作业类似于前面说过的 exe fd/* 等等.在多线程的程序中,如果主线程推出了此符号链接的内容将无法访问.

/proc/pid/smaps:该文件包含了进程的内存使用情况,与/proc/pid/maps文件类似,但提供了更详细的信息。

这个文件显示了每个进程映射的内存消耗.每一个内存消耗都有如下的设置:

08048000-080bc000 r-xp 00000000 03:02 13130 /bin/bash
Size: 464 kB
Rss: 424 kB
Shared_Clean: 424 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB

第一行显示的信息与/proc/[pid]/maps中的映射信息相同.剩下分别表示的是,映射的大小,RAM中当前驻留的映射大小,>> 映射中干净和脏共享页的大小以及映射中干净和脏共享私有页数.只有在启用了CONFIG_MMU内核配置选项时,此文>> 件才会存在.

/proc/pid/stat:该文件包含了进程的状态信息,如进程ID、父进程ID、状态、CPU使用情况等。

关于进程的状态信息.主要是用于 ps 展示.文件中的每一行的含义如下:

  1. pid %d 进程PID
  2. comm %s 可执行文件的文件名
  3. state %c 进程的状态,使用RSDZTW其中一个值表示.R表示正在运行,S表示因为中断休眠,D表示进程处于不可中断的睡眠, When a process will go to ‘D’ state?. Z表示僵尸进程,T表示正在被追踪或者停止,W表示现在正在进行叶交换.
  4. ppid %d 父进程PID
  5. grid %d 进程组ID
  6. session %d 进程的session id
  7. tty_nr %d 进程的控制终端
  8. tpgid %d 进程控制终端的前台进程id
  9. minflt %n 进程因为不需要从磁盘加载内存页而造成的次要故障数
  10. cminflt %u 进程等待子进程造成的次要故障数
  11. majflt %lu 进程需要从磁盘加载内存页造成的故障数
  12. cmajflt %lu 进程等待子进程造成的故障数
  13. utime %lu 进程在用户模式下被调度的时间
  14. stime %lu 进程在内核模式下被调度的时间
  15. cutime %ld 进程在用户模式下等待子进程的时间
  16. cstime %ld 进程在内核模式下等待子进程的时间
  17. nice %ld 参见 setpriority 位于19到-20之间.
  18. num_threads %ld 当前进程的线程数量
  19. vsize %lu 使用的虚拟内存
  20. rss %ld resident set szie的缩写,表示进程在实际内存中的页数,主要是包括了text,data,栈,不包括没有加载到内存中或者已经被换出去的内存大小
  21. rsslim %lu 进程rss的限制

还有一些不常见的字段,就不做说明了

/proc/pid/statm:该文件包含了进程的内存使用信息,如内存大小、共享内存大小、代码大小等。

与/proc/pid/stat文件类似。该文件的内容是一个文本字符串,包含了7个字段,分别是:

size:进程当前使用的总内存大小,单位是页面(page),即4KB。

resident:进程当前使用的常驻内存大小,即驻留集大小,单位是页面。

shared:进程当前使用的共享内存大小,单位是页面。

text:进程代码段的大小,单位是页面。

lib:进程动态链接库的大小,单位是页面。

data:进程数据段和堆的大小,单位是页面。

dt:进程动态加载库的大小,单位是页面。

这些字段的含义如下:

size:进程当前使用的总内存大小,包括常驻内存和非常驻内存,即驻留集大小 + 非驻留集大小。

resident:进程当前使用的常驻内存大小,即驻留集大小。

shared:进程当前使用的共享内存大小,包括共享库和共享内存段。

text:进程代码段的大小。

lib:进程动态加载库的大小。

data:进程数据段和堆的大小。

dt:进程动态加载库的大小,与lib字段相同。

通过读取/proc/pid/statm文件,可以了解进程的内存使用情况,方便进行进程管理和调试。例如,可以通过读取resident字段来了解进程当前使用的常驻内存大小,通过比较size和resident字段来了解进程当前使用的非常驻内存大小,通过读取shared字段来了解进程当前使用的共享内存大小等。


示例提供内存的使用情况.格式如下所示:

_size       (1) total program size
_           (same as VmSize in /proc/[pid]/status)
_resident   (2) resident set size
_           (same as VmRSS in /proc/[pid]/status)
_share      (3) shared pages (i.e., backed by a file)
_text       (4) text (code)
_lib        (5) library (unused in Linux 2.6)
_data       (6) data + stack
_dt         (7) dirty pages (unused in Linux 2.6)

/proc/pid/status:该文件包含了进程的状态信息,如进程的状态、CPU使用情况、内存使用情况等。

以更加可读的形式提供与/proc/pid/stat/proc/pid/statm一样的信息.以下是示例.

$ cat /proc/$$/status
Name: bash
State: S (sleeping)
Tgid: 3515
Pid: 3515
PPid: 3452
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 100 100 100 100
FDSize: 256
Groups: 16 33 100
VmPeak: 9136 kB
VmSize: 7896 kB
VmLck: 0 kB
VmHWM: 7572 kB
VmRSS: 6316 kB
VmData: 5224 kB
VmStk: 88 kB
VmExe: 572 kB
VmLib: 1708 kB
VmPTE: 20 kB
Threads: 1
SigQ: 0/3067
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000384004
SigCgt: 000000004b813efb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed: 00000001
Cpus_allowed_list: 0
Mems_allowed: 1
Mems_allowed_list: 0
voluntary_ctxt_switches: 150
nonvoluntary_ctxt_switches: 545
  1. VmPeak:代表当前进程运行过程中占用内存的峰值.
  2. VmSize:代表进程现在正在占用的内存
  3. VmLck:代表进程已经锁住的物理内存的大小.锁住的物理内存不能交换到硬盘.
  4. VmHWM:是程序得到分配到物理内存的峰值.
  5. VmRSS:是程序现在使用的物理内存.
  6. VmData:表示进程数据段的大小.
  7. VmStk:表示进程堆栈段的大小.
  8. VmExe:表示进程代码的大小.
  9. VmLib:表示进程所使用LIB库的大小.
  10. VmPTE:占用的页表的大小.
  11. VmSwap:进程占用Swap的大小.
  12. Threads:表示当前进程组的线程数量.
  13. SigPnd:屏蔽位,存储了该线程的待处理信号,等同于线程的PENDING信号.
  14. ShnPnd:屏蔽位,存储了该线程组的待处理信号.等同于进程组的PENDING信号.
  15. SigBlk:存放被阻塞的信号,等同于BLOCKED信号.
  16. SigIgn:存放被忽略的信号,等同于IGNORED信号.
  17. SigCgt:存放捕获的信号,等同于CAUGHT信号.
  18. CapEff:当一个进程要进行某个特权操作时,操作系统会检查cap_effective的对应位是否有效,而不再是检查进程的有效UID是否为0.
  19. CapPrm:表示进程能够使用的能力,在cap_permitted中可以包含cap_effective中没有的能力,这些能力是被进程自己临时放弃的,也可以说cap_effective是cap_permitted的一个子集.
  20. CapInh:表示能够被当前进程执行的程序继承的能力.
  21. CapBnd:是系统的边界能力,我们无法改变它.
  22. Cpus_allowed:3指出该进程可以使用CPU的亲和性掩码,因为我们指定为两块CPU,所以这里就是3,如果该进程指定为4个CPU(如果有话),这里就是F(1111).
  23. Cpus_allowed_list:0-1指出该进程可以使用CPU的列表,这里是0-1.
  24. voluntary_ctxt_switches:表示进程主动切换的次数.
  25. nonvoluntary_ctxt_switches:表示进程被动切换的次数.

/proc/pid/task:该目录包含了当前进程的线程列表,每个线程都有一个对应的子目录。

该目录包含的是进程中的每一个线程.每一个目录的名字是以线程ID命名的(tid).在每一个tid下面的目录结构与/proc/pid下面的目录结构相同.对于所有线程共享的属性,task/tid子目录中的每个文件内容与/proc/pid目录中的相应文件内容相同.例如所有线程中的task/tid/cwd文件和父目录中的/proc/pid/cwd文件内容相同,

因为所有的线程共享一个工作目录.对于每个线程的不同属性,task/tid下相应文件的值也不相同.


这些文件和目录都包含了关于进程的不同方面信息,通过读取它们,可以了解进程的状态、运行情况、资源使用情况、命名空间信息等等,方便进行进程管理和调试。


IV. /proc/pid文件的权限和安全性

/proc/pid是一个虚拟文件系统,它提供了与进程相关的系统信息。每个进程都有一个对应的/proc/pid目录,其中包含了许多文件和子目录,用于提供有关该进程的信息。在Linux系统中,/proc/pid文件的权限和安全性非常重要。

/proc/pid文件的权限

在Linux系统中,/proc/pid文件的权限由内核控制。默认情况下,只有root用户才能访问其他用户的/proc/pid目录。这是因为/proc/pid目录包含了许多敏感信息,如进程的内存映射、打开的文件、网络连接等。如果其他用户可以访问这些信息,可能会导致安全问题。

如果需要允许其他用户访问/proc/pid文件,可以通过更改文件权限或使用访问控制列表(ACL)来实现。但是,这样做可能会导致系统安全问题,因此需要谨慎处理。

为了保护/proc/pid文件的安全性,Linux系统提供了一些安全机制,如SELinux和AppArmor。这些机制可以帮助管理员加强对/proc/pid文件的访问控制,从而提高系统的安全性。

需要注意的是,即使只有root用户可以访问/proc/pid文件,但如果系统中存在恶意软件或攻击者,他们可能会通过各种手段获取/proc/pid文件中的信息,从而导致系统安全问题。因此,在保护/proc/pid文件的安全性方面,不仅仅是访问权限的控制,还需要综合考虑系统的整体安全性。

/proc/pid文件的安全性

由于/proc/pid文件包含了有关进程的敏感信息,因此对其进行保护非常重要。Linux系统通过内核控制/proc/pid文件的访问权限,以确保只有授权用户可以访问这些文件。此外,Linux系统还提供了许多安全工具和技术,如SELinux和AppArmor,以进一步保护/proc/pid文件的安全性。

需要注意的是,即使只有root用户可以访问/proc/pid文件,但如果系统中存在恶意软件或攻击者,他们可能会通过各种手段获取/proc/pid文件中的信息,从而导致系统安全问题。因此,在保护/proc/pid文件的安全性方面,不仅仅是访问权限的控制,还需要综合考虑系统的整体安全性。


V. /proc/pid的应用

/proc/pid是Linux系统中非常重要的一个虚拟文件系统,它提供了与进程相关的系统信息。/proc/pid文件可以用于许多用途,如进程监控和调试、进程性能分析和系统安全检测等。

进程监控和调试

在Linux系统中,/proc/pid文件可以用于进程监控和调试。管理员可以使用/proc/pid文件中的信息来了解进程的运行状态、资源使用情况和性能特征,从而帮助诊断和解决问题。例如,管理员可以使用/proc/pid文件中的状态信息来了解进程是否在运行、是否被挂起或停止,还可以使用/proc/pid文件中的内存映射信息来了解进程的内存使用情况。

进程性能分析

/proc/pid文件还可以用于进程性能分析。管理员可以使用/proc/pid文件中的信息来了解进程的性能特征,从而帮助优化系统性能。例如,管理员可以使用/proc/pid文件中的CPU使用情况和内存使用情况等信息来了解进程的资源使用情况,从而帮助识别性能瓶颈并进行优化。

系统安全检测

/proc/pid文件还可以用于系统安全检测。管理员可以使用/proc/pid文件中的信息来了解进程的运行状态和行为,从而帮助检测系统中的安全问题。例如,管理员可以使用/proc/pid文件中的网络连接信息来了解进程的网络行为,从而帮助检测是否存在未经授权的网络连接或恶意行为。

总之,/proc/pid文件是Linux系统中非常重要的一个虚拟文件系统,它提供了与进程相关的系统信息。/proc/pid文件可以用于许多用途,如进程监控和调试、进程性能分析和系统安全检测等,帮助管理员更好地管理和维护系统。


简单的C++获取获取示例

ProcPidHandler.h

#ifndef PROCPIDHANDLER_H
#define PROCPIDHANDLER_H
#include <string>
class ProcPidHandler { 
public:
    /**
     * 构造函数,接受一个进程ID作为参数。
     *
     * @param[in] pid 要处理的进程ID。
     */
    explicit ProcPidHandler(int pid);
    /**
     * 获取进程的指定信息。
     *
     * @tparam T 信息类型。
     * @param[in] infoType 要获取的信息类型。
     * @return 进程的指定信息。
     */
    template <typename T>
    T getInfo(const std::string& infoType) const;
private:
    int pid_;  // 进程ID };
#endif  // PROCPIDHANDLER_H 

在这个示例中,getInfo()方法是一个模板方法,它接受一个字符串参数,表示要获取的信息类型,然后返回相应类型的信息。这样,你可以使用同一个方法来获取不同类型的信息,只需要传入不同的参数即可。

然而,这个示例仍然是非常基础的,你可能需要根据你的具体需求来修改或扩展这个类。例如,你可能需要添加错误处理代码,或者添加更多的方法来处理更复杂的情况。

这是一个基本的C++类源文件的示例,用于处理/proc/pid的信息。这个类被命名为ProcPidHandler,它有一个构造函数,接受一个pid作为参数,并有一个模板方法用于获取不同的/proc/pid信息。

ProcPidHandler.cpp

#include "ProcPidHandler.h"
#include <fstream>
#include <sstream>
ProcPidHandler::ProcPidHandler(int pid) : pid_(pid) {}
template <typename T> T ProcPidHandler::getInfo(const std::string& infoType) const {
    std::stringstream ss;
    ss << "/proc/" << pid_ << "/" << infoType;
    std::ifstream file(ss.str());
    if (!file) {
        throw std::runtime_error("Unable to open file: " + ss.str());
    }
    T info;
    file >> info;
    return info; 
    }

在这个示例中,getInfo()方法是一个模板方法,它接受一个字符串参数,表示要获取的信息类型,然后返回相应类型的信息。这样,你可以使用同一个方法来获取不同类型的信息,只需要传入不同的参数即可。

注意,这只是一个基本的示例,你可能需要根据你的具体需求来修改或扩展这个类。例如,你可能需要添加错误处理代码,或者添加更多的方法来获取其他/proc/pid信息。

VI. 结论

/proc/pid是Linux系统中一个非常重要的虚拟文件系统,它提供了与进程相关的系统信息。/proc/pid文件可以用于许多用途,如进程监控和调试、进程性能分析和系统安全检测等,帮助管理员更好地管理和维护系统。总之,/proc/pid的作用和重要性如下:

提供进程相关的系统信息:/proc/pid目录提供了与特定进程相关的系统信息,如进程状态、内存使用情况、资源限制、网络连接等,帮助管理员了解进程的运行情况和行为。

支持进程监控和调试:管理员可以使用/proc/pid文件中的信息来了解进程的运行状态、资源使用情况和性能特征,从而帮助诊断和解决问题。

支持进程性能分析:管理员可以使用/proc/pid文件中的信息来了解进程的性能特征,从而帮助优化系统性能。

支持系统安全检测:管理员可以使用/proc/pid文件中的信息来了解进程的运行状态和行为,从而帮助检测系统中的安全问题,如恶意软件、未经授权的网络连接等。

为了更好地使用/proc/pid文件,管理员可以使用一些相关的命令和工具,如:

ps命令:用于列出当前系统中的进程,包括进程ID、进程名、父进程ID等信息。

top命令:用于实时监控系统中的进程,包括CPU使用情况、内存使用情况等信息。

lsof命令:用于列出当前系统中打开的文件和进程,包括文件描述符、进程ID等信息。

strace命令:用于跟踪进程的系统调用和信号,帮助调试和诊断进程问题。

总之,/proc/pid文件是Linux系统中一个非常有用的工具,它可以帮助管理员更好地了解和管理系统和进程,从而提高系统的稳定性和安全性


目录
相关文章
|
14天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
45 4
linux进程管理万字详解!!!
|
5天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
41 8
|
6天前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
23 5
|
9天前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
26 6
|
14天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
47 4
|
15天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
16天前
|
消息中间件 存储 Linux
|
22天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
24 1
|
4月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
4月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
166 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)