【Unix】进程控制

一、进程

进程ID为0是调度进程,常被称为交换进程swapper,该进程并不执行任何磁盘上的程序--它是内核的一部分,也被称为系统进程。

进程ID为1是init进程,在自举过程结束时由内核调用。

进程ID为2是页精灵进程,此进程负责支持虚存系统的请页操作。也是内核进程。

二、fork

对于父进程已经终止的所有进程,它们的父进程都改变为init进程,我们称这些进程由init进程领养。

此保证了每个进程有一个父进程。

init被编写成只要有一个子进程终止,init就会调用一个wait函数取得其终止状态。防止系统中有很多僵死进程。

 

三、wait和waitpid函数

1、当一个进程正常或异常终止时,内核就向其父进程发生SIGCHLD信号。

2、两个函数的区别

在一个子进程终止前,wait使其调用者阻塞,而waitpid有一选择项,可使调用者不阻塞。

waitpid并不等待第一个终止的子进程--它有许多个选择项,可以控制它所等待的进程。
四、exec函数

exec函数在当前进程中加载并运行包含可执行文件a.out中的程序,用a.out有效地替代了当前程序:

加载a.out的步骤:

删除已经存在的用户区域

映射私有区域、共享区域

设置程序计数器

五、进程的终止

1、五种方式

2、正常:

从main返回

调用exit

调用_exit

3、异常:

调用abort

由一个信号终止

  4、exit和_exit区别

_exit立即进入内核,由POSIX.1说明,而exit则先执行一些清除处理(调用各终止处理程序,关闭所有标准IO流等),

然后进入内核,由ANSI C说明。

5、内核使程序执行的唯一方法是调用一个exec函数。

6、进程自愿终止的唯一方法是显式调用_exit函数或隐式地调用_exit(通过调用exit)。

进程也可以非自愿的由一个信号使其终止。

 

六、终端登录

1、系统管理者创建一个通常名为/etc/ttys的文件,其中,每个终端设备有一行,每一行说明设备名和传到getty程序的参数。

当系统自举时,内核创建进程ID1,也就是init进程。init进程使系统进入多用户状态。

init读文件/etc/ttys,对每一个允许登录的终端设备,调用一次fork,它所生成的子进程则执行程序getty。

2、getty对终端设备调用open函数,以读、写方式将终端打开。

一旦设备被打开,则文件描述符0、1、2就被设置到该设备,然后getty输出“login:”之类的信息,并等待用户键入用户名。

3、当用户键入用户名后,getty就完成了,然后调用login程序。

4、因为最初的init进程具有超级用户优先权,所以其上所有进程都具有超级用户优先权。

5、如果用户登录正确,login就将当前工作目录更改为该用户的起始目录,它也调用chown改变终端的所有权。

6、然后登录shell,类似于 execl("/bin/sh", "-sh", (char *)0);

7、至此,登录用户的登录shell开始运行,其父进程ID是init进程(ID为1),所以当此登录shell终止时,init会得到通知,它会

对该终端重复全部上述过程。

 

七、网络登录

1、网络登录,所有登录都经由内核的网络界面驱动程序,事先并不知道将会有多少这样的登录。

有一个称为inetd的进程,它等待大多数网络连接。

2、作为系统启动的一部分,init调用一个shell,使其执行shell脚本/etc/rc。由此shell脚本启动一个精灵进程inetd。一旦此shell

脚本终止,inetd的父进程就变成init。inetd等待TCPIP连接请求到达主机,而当一个连接请求到达时,它执行一次fork,然后

该子进程执行适当的程序。

3、telnetd进程打开一个伪终端设备,并用fork生成一个子进程。

父进程处理通过网络连接的通信,子进程则执行login程序。父子进程通过伪终端相连接。

在调用exec之前,子进程使其文件描述符0、1、2与伪终端相连。

 

八、进程组

每个进程处理有一个进程ID之外,还属于一个进程组。

每个进程组有一个组长进程,其ID等于进程组ID。

 

九、对话期(session)

对话期是一个或多个进程组的集合。

shell执行程序时,其程序为shell的子进程。

对于管道,则管道的最后一个进程是登录shell的子进程。当该进程终止时,shell得到通知。

 

十、总结

进程是一个抽象的概念,由操作系统来维持,所以可以当作是真实,认为就是一个实实在在存在的。

进程涉及到了操作系统的方方面面,理解进程、进程间通信是王道。

 

你可能感兴趣的:(【Unix】进程控制)