转载请说明出处: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字段,可以获知每个进程的父进程。