文章目录
- 为什么要有进程等待?
- 如何等待和什么是等待?
为什么要有进程等待?
1.子进程退出,父进程不管子进程,子进程就要处于僵尸状态------会导致内存泄漏
2.父进程创建子进程是要让子进程办事的,那么子进程把任务完成的怎么样?
子进程做任务的结果:
a.代码跑完,结果正确
b.代码跑完,结果不正确
c.代码没跑完,程序崩溃
父进程需要关心吗?如果需要如何得知?如果不需要该怎么处理?
以上就是为什么要进程等待的结果。
总结进程等待的必要性:
- 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
- 另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。
- 最后,父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。
- 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息
如何等待和什么是等待?
进程等待方法:
wait:基本验证回收僵尸进程的问题
waitpid:获取子进程退出结果的问题
代码演示:
僵尸进程问题:
解决僵尸进程问题:
用wait函数解决:
wait函数是阻塞式等待
我们可以看到僵尸进程确实得到了回收。
为了能更好的看清我们对代码进行改进:
这回我们可以清楚的看到子进程先是S态然后是Z态最后被回收。
用waitpid解决:
我们可以看到waitpid有三个参数。
pid:要等待进程的pid,如果传入的是-1表示等待任一个进程
status:输出型参数
options:如果传入0为阻塞式等待
上面讲了status是输出型参数那么具体是干什么的呢?
status:可以获取子进程退出结果。
但是status并不是按照整数来整体使用的,而是按照比特位,将32个比特位进行划分,我们只学习第16位。
status次低8位为退出状态码:
演示:
我们可以看到退出码为0;
那么我们改一下看一下,改成10.
我们看到确实退出码为10.
status:低7位为退出信号
演示:
在原先的基础上多输出一个退出信号。
正常退出信号为0;
异常退出测试:
我们手动杀死子进程
我们可以看到退出信号为9
程序异常退出或者崩溃,本质是OS杀掉了该进程。
操作系统如何杀掉呢?
本质是OS发送信号杀掉的。
所以程序异常不光光是内部代码有问题,也可能是外力直接杀掉。
父进程通过wait/waitpid可以拿到子进程的退出结果,那么为什么要用wait和waitpid呢?直接用全局变量不行吗?
不行,因为进程具有独立性,那么当数据发生改变是就会发生写时拷贝,父进程无法拿到子进程全局变量的地址。
既然进程具有独立性,进程退出码不也是子进程的数据吗?父进程又凭什么拿到呢?wait和waitpid究竟干了什么呢?
僵尸进程:至少要保留该进程的PCB信息!task_struct里面保留了任何进程退出时的退出信息结果。