1. 进程终止方式

进程终止的方式有5种正常终止方式以及3种异常终止方式。正常终止方式主要包括在 main 函数返回、调用 exit 函数等。异常终止方式包括调用 abort 、接受信号等。

不管进程如何终止,最后都会执行内核中的同一段代码,关闭进程所以打开描述符,释放它所使用大部分资源。

2. 进程终止状态

父进程可能会对子进程的执行情况感兴趣。在进程终止的时候,我们希望能够将子进程的终止状态(termination status)告知父进程。

2.1 终止状态如何产生

  • 当使用终止函数(exit, _exit_Exit)终止进程的时候,进程的退出状态(exit status)作为参数传递给终止函数,内核将退出状态转化为终止状态;
  • 在异常终止的情况下,内核将产生一个指示其异常终止原因的终止状态。

2.2 终止状态如何传递

父子进程的终止顺序可以有先后,如何保证子进程的终止状态告知父进程?

操作系统会维护一张进程表(process table),进程表的每个条目包含了进程所有必须的信息。当进程终止的时候,进程占用的大部分资源都被释放了,但仍保留了少量的信息,包括进程的 ID 、进程的终止状态码、以及进程所使用的 CPU 时间总量。

当子进程先于父进程终止时,父进程可以通过 waitwaitpid 等函数获取内核保留的终止状态。

当父进程先于子进程终止时,子进程会被 init 进程领养,init 进程称为该进程的父进程。而 init 进程无论何时,只要有一个子进程终止,都会调用 wait 函数来获取其终止状态。

3. zombie 进程

zombie 进程是指一个已经终止,但其父进程尚未对其进行善后处理的进程。因为内核还保留着关于该进程的终止状态等信息,所以该进程仍然占用资源。

那么问题是,为什么要确保除了交换进程(swapper process,PID=0)以外,每个进程都有一个父进程呢?想一想哦~

4. 笔记来源

Advanced Programming in the UNIX Environment, 3rd Edition