剧情引入-功能简介
首先在介绍这两个函数之前那必须得介绍一下这两个函数的使用场景,wait和waitpid的功能都是为了回收子进程资源,因为子进程被创建出来之后,会申请一份空间(32位操作系统是4G),那这个子进程做完自己的任务后准备结束时,需要将申请的这份空间给释放掉,那么内核规定了,子进程的资源应该由父进程来回收,所以子进程会一直等待父进程来回收资源,在此期间会产生一个没有灵魂的躯壳进程,也被称之为僵尸态。那么有程序员通过fork函数接口创建出来的子进程天生就知道要父进程回收自己的资源,但是父进程在创建的过程之中并不具备回收资源的能力,所以需要在父进程调用wait 和 waitpid来回收子进程资源,避免空间没有释放的现象发生。当然,如果父进程结束之前都没有回收子进程资源,子进程的资源就永远不会释放了吗?答案:当然并不是,操作系统不没有那么不完善,它也规定了一个当父进程结束后,并没有回收子进程的动作,那么子进程会认为1号init进程为他的父进程,那么1号进程中也具备回收子进程的能力。此过程称为收养过程,那么这样的进程被称为孤儿进程。
僵尸进程
僵尸进程的概念很简单:就**是子进程优先于父进程先结束,父进程不具备回收子进程资源的能力,或者说父进程还没有运行到回收子进程资源的代码。**那么子进程的又不能越界去让init进程收养,所以说子进程就变成了僵尸进程。
那么子进程结束也就代表着子进程没有任何作用了,但是还要占用资源,所以现阶段的子进程就存在一定的危害,如果这样的僵尸进程越来越多的话,会导致内存不够用从而造成fork的失败。
所以说为了解决这个问题,我们一般使用wait和waitpid在父进程上添加上回收子进程资源的功能。
回收子进程资源,避免僵尸进程
wait
功能:阻塞等待回收任意一个子进程资源
阻塞:停下来,不在向下执行函数。
头文件:
#include <sys/types.h>
#include <sys/wait.h>
原型:pid_t wait(int *wstatus);
参数:
wstatus :释放掉的子进程的结束状态
如果不考虑子进程的退出状态直接使用NULL
返回值:
成功返回:回收到的子进程的ID号
失败返回:-1代表着错误
注意:wait的参数wstatus,是由exit进程结束函数或者说_exit结束进程函数返回。
详细信息代码上有所体现
wait示例代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
//创建一个子进程
pid_t pid = fork();
if(