聊聊PID 那些事儿

PId?

计算机里,每个进程在创建的时候会有一个唯一标识(process identifier)所以我们一般都管他们叫Process ID或者直接缩写PID。

这个ID一般是由操作系统内核创建的(比如Unix、MacOS、Windows .etc),用来唯一标记一个活跃的进程。在函数调用时,这个PID可以作为一个参数来使用,比如调整进程的优先级,或者终止进程等。

Unix系系统

在Unix系的操作系统里,新的进程会通过调用系统的
fork()
来创建。这个进程的PID会由父进程直接返回,方便以后的子进程进行调用。父进程有可能会通过waitpid()来等待子进程结束,或者直接调用kill()来杀掉这个进程。

但是有两个task会拥有独特的PID:swappersched用0作为PID,因为他们是用来做内存分页的,其实讲道理,他们应该算内核的一部分而不算用户进程。PID 1 常用来标记初始化进程,主要用做启动和关闭系统。本来 PID 1并不是专门预留的进程ID,只是因为init 进程是计算机内核创建的第一个进程,所以init 进程基本上都会得到PID 1. 现在大部分都Unix操作系统已经有了其他的以进程形式存在的组件,但是初始化进程还是被标记为PID 1,只是为了和以前的系统保持一致(兼容)。

PID,一般都是从0开始分配,一直到系统定义的最大值。一旦到达了,就从300重新开始递增。

MacOSHP-UX里一般会从100开始重新分配。

那么问题就来了,这个300/100是什么梗?为毛要从这里开始而不是从…比如666开始?在Linux/Unix内核代码里面hardcode了一段
#define RESERVED_PIDS 300
emmm…目测只是因为Linus同学一拍脑袋想出来的…whetever吧。参考这一页

重新从300(100)开始之后,如果遇到已经分配过的PID就会跳过。所以有的人认为这会是一个潜在的系统漏洞,因为它需要允许进程读取系统信息,或者在进程之间传递信息。为此,为了解决这个潜在的漏洞,可以选择其他更复杂的PID分配算法。

在某些操作系统里面,比如MPE/iX,使用最低可用PID,有时是为了最小化内存中的进程信息内核页面的数量。
这个PID是通过getpid()这个系统调用,或者通过shell命令$$。父进程的PID可以通过getppid()来获取。

Linux里面,最大的PID是记录在/可以通过“伪”文件/proc/sys/kernel/pid_max访问。

WIndows系系统

Windows系统里面,我们可以通过调用GetCurrentProcessId()来获取当前的PID,或者通过调用GetProcessId()来获取其他进程的PID。在系统内部,PID被称为client ID,而且它们和线程ID位于同一个命名空间里,所以这两兄弟是不会出现重合的。那个System Idle Process顶着PID0,系统进程顶着PID 4. 在某些版本的Windows,进程和线程ID都是4的倍数,不过这并不是一个标准设置。

PID文件

在某些进程中,比如moc音乐播放器或者MySQL的守护进程, 他们会写自己本地的PID文件,同时也会允许其他进程访问。

参考资料:wikipedia

猜你喜欢

转载自blog.csdn.net/weixin_40601534/article/details/84260001