30 linux 新建进程的进程号是如何分配的?

前言

呵呵 进程号是我们经常使用到的, 但是 却从来 没有深究过的东西 

这里 就来看一下 具体的进程号的生成方式 

linux 新建进程是以 fork + exec 的形式创建进程的 

子进程 是 复制自 父进程 

pid 是怎么生成的?

分配 pid 的地方调用堆栈如下, fork 之后, 会为 新进程 申请 pid, 具体的地方如下 

分配是基于 pid_namespace 

其中记录的有上一次分配的 pid 的大小, pid 为 上次的pid +1 

然后尝试在 pid_ns 的 pid_bitmap 中尝试更新 pid 为使用, 如果更新成功, 则使用当前 pid 

若果更新不成功, 则在 pid_ns 的 pid_bitmap 中获取下一个可用的索引, 然后 进行重试 

如果当前 pid_bitmap 尝试到末尾依然没有找到可用的 pid, 尝试查找下一块 pid_bitmap [如果当前是 最后一块 pid_bitmap, 则下一个 pid_bitmap 为第一块 pid_bitmap] 

关于这里的多个 pid_bitmap, 默认情况下是只会使用一个 pid_bitmap 

BITS_PER_PAGE 为 4k * 8 = 32768, pid_max 默认为 32768, 因此这里的 pid_bitmap 最多会使用一个元素 

这里的 pid_bitmap 的内存是使用的一个 物理页 来维护的 

按照大多数的正常情况 下一个进程号, 即为最大进程号 + 1 

如果 分配到了 pid_max[默认为 32768], 则从 第一个 pid_bitmap 的 第一个 pid 开始尝试 

测试 pid 的相关规则, 写一个脚本 一直 "ps -l" + "grep ps"

脚本大致如下 

ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps
ps -l | grep ps

测试输出大致如下

... 
R     0 14978   287  4680   844 0:0   06:41 00:00:00 {exe} ps -l
R     0 14979   287  4676   700 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14980   287  4680   840 0:0   06:41 00:00:00 {exe} ps -l
R     0 14981   287  4676   840 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14982   287  4680   712 0:0   06:41 00:00:00 {exe} ps -l
R     0 14983   287  4676   784 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14984   287  4680   792 0:0   06:41 00:00:00 {exe} ps -l
R     0 14985   287  4676   732 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14986   287  4680   680 0:0   06:41 00:00:00 {exe} ps -l
R     0 14987   287  4676   740 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14988   287  4680   784 0:0   06:41 00:00:00 {exe} ps -l
R     0 14989   287  4676   792 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14990   287  4680   696 0:0   06:41 00:00:00 {exe} ps -l
R     0 14991   287  4676   792 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14992   287  4680   692 0:0   06:41 00:00:00 {exe} ps -l
R     0 14993   287  4676   836 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14994   287  4680   696 0:0   06:41 00:00:00 {exe} ps -l
R     0 14995   287  4676   712 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14996   287  4680   716 0:0   06:41 00:00:00 {exe} ps -l
R     0 14997   287  4676   692 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 14998   287  4680   676 0:0   06:41 00:00:00 {exe} ps -l
R     0 14999   287  4676   712 0:0   06:41 00:00:00 {exe} grep ps
S     0   287   275  4676  1468 0:0   03:33 00:01:47 {exe} ash ./psCmd.sh
R     0 15000   287  4680   688 0:0   06:41 00:00:00 {exe} ps -l
R     0 15001   287  4676   740 0:0   06:41 00:00:00 {exe} grep ps

猜你喜欢

转载自blog.csdn.net/u011039332/article/details/128158963