这是一个纯粹的学术问题,因为这永远不会发生。
如果 PID 存储为 pid_t 类型,而不是某种任意精度类型,则一次可以存在的 PID 数量是有限的。 PID 溢出时是否有定义的行为?
第 65536 个进程会杀死 /sbin/init 并造成内核恐慌吗?或者有什么安全措施吗?
答案1
POSIX 并没有规定每个新进程的 PID 都是通过增加先前的 PID 来获得的。它只要求它是唯一的。
在每个 PID 都递增的系统上fork()
,我观察到这些值在达到某个上限(根据我的经验约为 2 15)后会回绕。回绕后,新的 PID 不会严格递增,因为某些 PID 值仍将使用先前周期中的值。
在你有 2 N之前应该不会有问题 同时运行流程。我怀疑系统早在这件事发生之前就已经遇到了一些容量限制。在这种情况下,fork()
系统调用将失败并可能设置errno
为EAGAIN
或ENOMEM
(man 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
答案3
最大 PID 限制远小于2^((sizeof(int)*CHAR_BIT)
。看进程ID的最大值是多少?。换句话说,你的 PID 永远不会接近 40 亿。
当所有 pid 槽都被填满时,fork
调用将开始失败errno==EAGAIN
(请参阅叉子(2))。如果你只是简单地到达顶部而不填充所有槽,则下一个PID将是1之后的下一个空闲槽(1是init)