《Linux应用文件编程(三) — 进程相关》
1. 进程ID
Linux 下每个进程都会有一个非负整数表示的唯一进程 ID。
Linux 提供了 getpid 函数来获取进程的 pid ,同时还提供了 getppid 函数来获取父进程的 pid。
#include <sys/types.h> #include <unistd.h> pid_t getpid(void); pid_t getppid(void);
进程退出以后,其进程 ID 还可以再次分配给其他的进程使用。
Linux 分配进程 ID 的算法不同于给进程分配文件描述符的最小可用算法,它采用了延迟重用的算法,即分配给新创建进程的 ID 尽量不与最近终止进程的 ID 重复,这样就可以防止将新创建的进程误判为使用相同进程 ID 的已经退出的进程。
那么如何实现延迟重用呢?内核采用的方法如下:
1 )位图记录进程 ID 的分配情况( 0 为可用, 1 为已占用)。
2 )将上次分配的进程 ID 记录到 last_pid 中,分配进程 ID 时,从 last_pid+1 开始找起,从位图中寻找可用的 ID 。
3 )如果找到位图集合的最后一位仍不可用,则回滚到位图集合的起始位置,从头开始找。既然是位图记录进程 ID 的分配情况,那么位图的大小就必须要考虑周全。位图的大小直接决定了系统允许同时存在的进程的最大个数,这个最大个数在系统中称为 pid_max 。
Linux/Unix分配进程ID的方法以及源代码实现 - clnchanpin - 博客园 (cnblogs.com)
上面的第 3 步提到,回绕到位图集合的起始位置,从头寻找可用的进程 ID 。事实上,严格说来,这种说法并不正确,回绕时并不是从 0 开始找起,而是从 300 开始找起。内核在 kernel/pid.c 文件中定义了RESERVED_PIDS ,其值是 300 , 300 以下的 pid 会被系统占用,而不能分配给用户进程:
define RESERVED_PIDS 300 int pid_max = PID_MAX_DEFAULT;
Linux 系统下可以通过 procfs 或 sysctl 命令来查看 pid_max 的值:
manu@manu-rush:~$ cat /proc/sys/kernel/pid_max 131072 manu@manu-rush:~$ sysctl kernel.pid_max kernel.pid_max = 131072