Linux系统下进程回收--wait()函数

发布时间 2023-04-01 10:07:03作者: nakejimamiyuki

进程回收

  • 在每个进程退出的时候,内核释放该进程所有资源‘包括打开的文件、占用的内存等。但是仍然会保存一定的信息,这些信息主要是进程控制块PCB的信息(包括进程号、退出状态、运行时间等)。
  • 父进程可以调用wait()或waitpid()函数得到它的退出状态,同时彻底清除这个进程。
  • wait()函数和waitpid()函数的功能一样,区别在于wait()函数会阻塞,waitpid()函数可以设置不阻塞,waitpid()还可以指定等待哪个子进程结束。
  • 注意:一次wait或者waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

wait()函数

在Linux终端下使用命令:man 2 wait查看wait函数的具体描述:

NAME
       wait, waitpid, waitid - wait for process to change state

SYNOPSIS
       #include <sys/types.h>
       #include <sys/wait.h>

        pid_t wait(int *wstatus);
            作用:
                等待任意一个子进程结束,如果任意一个子进程结束了,该函数就会回收子进程的资源。
            参数:
                int *wstatus:进程退出时的状态信息,传入的是一个int类型的地址,传出参数。
            返回值:
                - 成功:返回被回收的子进程的id
                - 失败:返回-1(调用函数失败,或者所有子进程都被回收)

            调用wait函数的进程会被挂起(阻塞),直到它的一个子进程退出或者收到一个不能被忽略的信号时才被唤醒(相当于继续往下执行).
            如果没有子进程,函数立刻返回-1,如果子进程都已经结束了,也会立刻返回-1.

下面是wait函数的简单案例:

#include <iostream>
#include <unistd.h>
#include <stdlib.h>

using std::cout;
using std::endl;

namespace wait_test{

    void test(){

        //有一个父进程创建5个子进程
        pid_t pid;

        //创建5个子进程
        for(int i=0;i<5;++i){
            pid = fork();
            if(pid == 0)
                break;
        }

        if(pid>0){
            //父进程
            while(1){
                cout<<"parent,pid:"<<getpid()<<endl;

                //int ret = wait(NULL);
                int st;
                int ret = wait(&st);

                if(ret == -1)
                    break;
                
                if(WIFEXITED(st))
                    //是不是正常退出
                    cout<<"退出的状态码:"<<WEXITSTATUS(st)<<endl;
                if(WIFSIGNALED(st))
                    //是不是异常终止
                    cout<<"被哪个信号干掉了:"<<WTERMSIG(st)<<endl;
                cout<<"child has died,pid:"<<ret<<endl;
                sleep(1);
            }
        }
        else if(pid == 0){
            //子进程
            //while(1){
            cout<<"child, pid:"<<getpid()<<endl;
            sleep(1);    
            //}
            exit(0);
        }
    }

    
}


int main(){

    wait_test::test();
    //waitpid_test::test();
    return 0;
}