PID是如何产生的?


42

在* nix上,PID是正在运行的进程的唯一标识符。PID是如何产生的?它只是递增的整数还是更复杂的结构(如列表)?它们如何回收?通过回收,我的意思是,当一个进程终止时,它的PID将最终被另一个进程重用。


Answers:


39

正如维基百科所说,

在Unix下,进程ID通常是按顺序分配的,从0开始,直到每个系统的最大值都增加。一旦达到此限制,分配将从零重新开始,然后再次增加。但是,对于此遍和后续遍,将跳过仍分配给进程的所有PID。

因此,对于“生成”来说,这实际上是一个非常简单的策略,只需增加一个计数器并“回收”,只需将数字包装在最大值处,然后不断增加,直到找到分配给已完成并具有已从过程表中删除。

某些Unix实现(例如AIX)使用的策略不太简单,请参见此FAQ


感谢您的回答。顺便说一下,这个“不太简单”的AIX策略到底是什么?

1
@Helltone,我不认为AIX会确切说明其使用的策略(因此它可以在任何发行版中更改),但是您可以将其视为在适当范围内的随机数生成(直到生成PID当前未使用)。
Alex Martelli 2010年

这个算法对我来说似乎有点问题。如何确保您不会陷入僵局?并且没有性能问题吗?

1
内核处于控制之中,不需要锁定任何东西,那么它怎么会死锁呢?是的,要付出的性能代价是很小的(在派生时付出的额外开销很小-说几打机器指令用于同等的PRNG或/ dev / urandom读取,而反之则少得多),但这总是旨在提高安全性的措施的情况(例如,检查HTTPS通信与纯HTTP的CPU开销;-)。
亚历克斯·马特利

我的意思是活锁(while(true);),对不起,我正在快速回答;-)

11

它会有所不同。

大多数系统只保留最后生成的PID的计数,添加一个(以最大数量包装,例如65535或更小-通常在65000甚至60000处发生包装),然后检查当前未使用该数量(如果PID仍在使用中,则重复此操作-因此,内核的PID 1仍然在那里并且不会被“重新发行”)。

其他注重安全性的系统会随机生成一个数字,并检查该数字是否在使用中。

在任何给定时间,可以确保所有PID号都是唯一的。


9

关于问题的回收部分,要记住的一件事是,一旦使用该pid的进程终止,该pid就不会变得可用。在该进程的父进程通过某种形式的wait()系统调用收集其子进程的终止状态之前,该pid才变为可用。被终止但其父母尚未发出等待的孩子称为僵尸,通常会以ps的形式显示为已失效。如果行为不端的父母启动了子进程而不为它们等待,则可能会饿死pids系统。

如果进程的父级在收集子级状态之前死亡,那就可以了。该子项由init继承,该init会确保发出了wait()并回收了pid。


这是一个非常重要的细节。没有它,即使是简单的myprog &跟随wait $!也将是UB。
安德烈亚斯

3

它们是序列号,如果系统运行了足够长的时间,则回绕(以特定于操作系统的值)。除非数字在时是免费的,否则永远不会重复使用它们fork()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.