前言:我们开始讲解进程等待,简单地讲解 wait 函数,然后我们主要讲解 waitpid 函数。由于 wait 只有一个参数 status,且 waitpid 有三个参数且其中一个也是 status,我们本章重点讲解这个 status 参数。
一、进程等待(Process wait)
1、进程等待的必要性
为什么要进行进程等待?不知道大家是否还记得我们在之前的章节讲过的 "僵尸进程" 的概念。
僵尸状态:当一个
中的进程退出的时候,一般不会直接进入
状态(死亡,资源可以立马被回收),而是进入
状态。
子进程退出如果父进程不管不顾,就 可能造成僵尸进程的问题,一直占内存进而引发内存泄露。
所以我们必须让其从 状态变为
状态:
进而允许操作系统能去释放它(将代码和数据 free 掉,将相关数据结构归还给 slab 分派器)。
上面我们讲的实际上就是我们需要进程等待的一个原因 —— 解决内存泄露问题 。
然而不仅仅这一个原因,我们还需要进程等待来 获取子进程的退出状态 。
我们需要知道父进程派给子进程的任务完成的如何。
比如子进程运行完成,结果对还是不对,是否正常退出?
通过进程等待的方式,回收子进程资源,获得子进程退出信息。
获取子进程的退出状态是否需要将曾经子进程的退出信息保存起来,然后被恢复、读取呢?
这和我们刚才讲的进程退出有着大大的关系!我们知道了进程退出是有退出码的。
我们需要让子进程退出时它的 return
结果或者 exit 的结果是需要被父进程读到的。
总结:需要进程等待的原因:① 解决内存泄露问题 ② 获取子进程的退出状态
2、wait 函数
函数原型是
#include <sys/types.h>
#include <wait.h>
int wait(int *status)
函数功能是:父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
我们看到,wait 有一个叫 status 的参数
我们下面验证一下这个函数是否可以 ,我们会把 status 暂且设置为空。
验证:
简单来说,就是让父子进程都跑起来,并各自打印消息,子进程一直死循环运行,父进程将自己休眠 20 秒,在这 20 秒之内我们手动把处于死循环的子进程给 kill 掉,此时子进程会处于