当 PID 耗尽时会发生什么?

当 PID 耗尽时会发生什么?

这是一个纯粹的学术问题,因为这永远不会发生。

如果 PID 存储为 pid_t 类型,而不是某种任意精度类型,则一次可以存在的 PID 数量是有限的。 PID 溢出时是否有定义的行为?

第 65536 个进程会杀死 /sbin/init 并造成内核恐慌吗?或者有什么安全措施吗?

答案1

POSIX 并没有规定每个新进程的 PID 都是通过增加先前的 PID 来获得的。它只要求它是唯一的。

在每个 PID 都递增的系统上fork(),我观察到这些值在达到某个上限(根据我的经验约为 2 15)后会回绕。回绕后,新的 PID 不会严格递增,因为某些 PID 值仍将使用先前周期中的值。

在你有 2 N之前应该不会有问题 同时运行流程。我怀疑系统早在这件事发生之前就已经遇到了一些容量限制。在这种情况下,fork()系统调用将失败并可能设置errnoEAGAINENOMEMman fork了解详细信息)。

实现的代码fork可能会也可能不会检查是否有任何 PID 可用。它可能不会打扰,因为它假设系统资源在到达该点之前已经耗尽,或者为了完整性和处理未来的可能性,它可能会进行显式检查。我还没有检查过,如果我检查过,我只能解决我所查看过的内核。

更新:在我当前的系统(Ubuntu 20.04)上,最大 PID 是 2 22,如下所示:

$ cat /proc/sys/kernel/pid_max
4194304

man proc

/proc/sys/kernel/pid_max(自 Linux 2.5.34 起)

该文件指定 PID 环绕的值(即该文件中的值比最大 PID 大 1)。大于该值的PID不分配;因此,该文件中的值还充当对进程和线程总数的系统范围限制。该文件的默认值 32768 会产生与早期内核相同的 PID 范围。在 32 位平台上,32768 是 pid_max 的最大值。在 64 位系统上,pid_max 可以设置为最大 2^22 的任何值(PID_MAX_LIMIT,大约 400 万)。

但具体的最大值可能与问题不太相关,除非您拥有 4+00000 个进程的可能性比拥有超过 32767 个进程的可能性更小。

答案2

系统fork调用应返回 -1,并设置errno伊加恩。之后发生的事情将取决于调用的进程fork

如果出现以下情况,fork() 函数将失败:

[再次]

系统缺乏创建另一个进程所需的资源,或者将超出系统对系统范围或单个用户执行的进程总数 {CHILD_MAX} 施加的限制。

答案3

最大 PID 限制远小于2^((sizeof(int)*CHAR_BIT)。看进程ID的最大值是多少?。换句话说,你的 PID 永远不会接近 40 亿。

当所有 pid 槽都被填满时,fork调用将开始失败errno==EAGAIN(请参阅叉子(2))。如果你只是简单地到达顶部而不填充所有槽,则下一个PID将是1之后的下一个空闲槽(1是init)

相关内容