每天进步一点点——重新认识Linux中的进程号

转载请说明出处:http://blog.csdn.net/cywosp/article/details/38968011


1. 概述
    众所周知,进程(process)是一个可执行程序的实例,但是在Linux中进程可以重新改写为,进程是由内核定义的抽象的实体,并为该实体分配用以执行程序的各项系统资源。从内核的角度看,进程由用户内存空间(user-space memory)和一系列内核数据结构组成,其中用户内存空间包含了程序代码及代码所使用的变量,而内核数据结构则用于维护进程状态信息。记录在内核数据结构中的信息包括许多与进程相关的标识号(IDs)、虚拟内存表、打开文件的描述符表、信号传递及处理的有关信息、进程资源使用及限制、当前工作目录及大量其他信息。

2. 进程描述符
    每一个进程都有一个进程号(PID),进程号是一个正数,用以唯一标识系统中的某个进程。对各种系统调用而言,进程号有时可以作为传入参数,有时可以作为返回值。比如,系统调用kill(()允许调用者向拥有特定进程号的进程发送一个信号。当需要创建一个对某进程而言唯一标识符时,进程号就会派上用场。常见的例子是将进程号作为与进程相关文件名的一部分(日志文件名)。在分布式系统中可以使用ip:port:start_time:pid来区分整个集群中的进程,这样可以完全保证唯一性,也可以在出问题后能快速定位。
    系统调用getpid()返回调用进程的进程号,声明如下:
    #include<unistd.h>
    // Always successfully returns process ID of caller
    pid_t getpid(void);

3. 进程描述符的系统限定
    Linux内核限制进程号需要小于等于32767。新进程创建时,内核会按顺序将下一个可用的进程号分配给其使用。每当进程号到达32767的限制时,内核将重置进程号计数器,以便从小整数重新开始分配。该分配方式具体如下:
    一旦进程号到达32767,内核会将进程号计数器重置为300,而不是1。之所以如此,是因为低数值的进程号为系统进程和守护进程长期占用,在此范围内搜索尚未使用的进程号只会是浪费时间。
    在Linux 2.4版本及更早版本中,进程号的上限是32767,由内核常量PID_MAX所定义。在Linux 2.6版本中,情况有所改变。尽管进程号的默认上限仍是32767,但是可以通过Linux系统特有的/proc/sys/kernel/pid_max文件来进行调整(其值=最大进程+1)。在32位平台中,pid_max文件的最大值为32767,但是在64位平台中,该文件的最大值可以高达2^22次方(约400万),系统可容纳的进程数量会非常庞大。

4. 父进程号
    每个进程都有一个创建自己的父进程。使用系统调用getppid()可以获取父进程的进程号,该函数声明如下:
    #include<unistd.h>
    // Always successfully returns ID of parent of caller
    pid_t getppid(void)
    实际上,每个进程的父进程号属性反映了系统上所有进程间的树状关系。每个父进程的父进程又有自己的父进程,以此类推,回溯到1号进程——init进程,即所有进程的始祖。使用pstree命令可以查看这一树状关系。
    如果子进程的父进程终止了,则子进程会变成“孤儿”,init进程随即将收养该进程,子进程后续对getppid()的调用将返回进程号1。通过查看由Linux系统所特有的/proc/PID/status文件所提供的PPid字段,可以获知每个进程的父进程。





郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。