一、进程等待的作用
父进程等待子进程退出,获取子进程的返回值,避免产生僵死进程。
二、如何实现进程等待
(1)wait函数
1. 函数原型:
pid_t wait(int *status)该函数是一个阻塞函数,功能是等待任意一个子进程退出。
2. 参数说明:
status:用于获取退出原因
3. 返回值:
返回值是退出的子进程的ID
(2)waitpid函数
1. 函数原型:
pid_t waitpid(pid_t pid,int* status,int options)
可以等待任意一个子进程退出或者等待指定子进程退出
2. 参数说明:
-
pid:
-1: 等待任意子进程退出
>0: 等待指定的子进程退出
-
status:
用于获取退出原因
-
-
options:
0: 默认为阻塞
WNOHANG: 将waitpid设置为非阻塞
4. 返回值: 函数的返回值只用了一个字节来接收,这一点要注意
-1: 错误
0: 有子进程,但是没有等到子进程退出
子进程的pid: 等到了子进程退出,返回退出子进程的pid
列举一种非阻塞的使用方法:while(waitpid(-1,NULL,WNOHANG)==0),如果没有子进程退出就一直等待。
三、阻塞与非阻塞
阻塞:为了完成功能,发起调用,如果当前不具备完成条件,则一直等待,直到完成后才返回。
非阻塞:为了完成功能,发起调用,如果当前不具备完成条件,则立即报错返回。
阻塞与非阻塞的区别:调用功能不具备完成条件时,是否立即返回。
非阻塞对于阻塞来讲对CPU的利用更加高效,因为它不需要等待,但是他需要进行循环操作才可以
四、子进程退出原因
子进程的退出原因,通常保存在stasus中。虽然status是一个4字节的int,但是实际上仅仅使用了一个字节去保存退出原因,也就是说其余三个字节是没有的,这同样意味着,退出原因最大不能超过255。
status分析
对于status来说,4个字节,32位的空间。其中高16位丢弃不用,子进程的退出返回值保存在低16中的高8位,其余的如上图所示。
如何获取子进程的返回值?
如果程序异常退出: 那么它的退出返回值就豪无参照意义,没必要获取
如果正常退出: 那么低7位就为0,所以如果低7位为0,就说明可以获取返回值。
代码如下:
if((statu & 0x7f)==0) //如果低7位为0,就说明可以获取返回值
(statu >>8) & 0xff;