在前面的文章中我们讨论了如何通过 fork() 函数创建子进程,创建后的子进程如果优先于父进程退出,子进程的虚拟内存空间就消失了,但是进程控制块PCB并没有消失,这里面包含了这个子进程的退出状态,需要由父进程来进行回收。在父进程回收之前,这个进程被称为僵尸进程(僵死进程),任何一个子进程都会经过这段僵尸进程的阶段,最后由父进程来回收。
子进程退出有两种情况,一种是程序正常退出了,比如exit(1)或者main函数返回等。而另外一种则是非正常退出,一般情况下是收到了某种信号,比如“kill -9”。正常退出的情况下,我们要获取进程退出的代码,而非正常退出的状态下我们要获取到底进程因为哪中信号而终止了。 我们首先来看一个最简单的 wait 函数的应用:
1 | #include <stdio.h> |
上面代码是一个最简单的 wait() 的应用了,这样的 wait() 只起到了回收子进程 PCB 的作用,而并没有对子进程的退出消息做任何的接收或处理。下面的代码演示了如何对子进程的退出情况做出响应。
1 | #include <stdio.h> |
从上面的例子中可以看出,WIFEXITED是用来判断子进程的退出状态的,如果返回真则证明子进程是正常退出的,随后使用了WEXITSTATUS获取了退出代码。而WIFSIGNALED则是判断子进程是否是接收到了某个信号,如果是收到了某个信号证明进程是非正常退出的,那么使用WTERMSIG获取收到的信号。可通过 kill -l 查看信号编号的对应内容。