wait()函数

时间:2019-08-06
本文章向大家介绍wait()函数,主要包括wait()函数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

wait()函数:回收僵尸进程

父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:

1) 阻塞等待子进程退出

2) 回收子进程残留资源

3) 获取子进程结束状态(退出原因)

/***
zoom_test.c
***/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, wpid;
    pid = fork();
    int status;
    
    if (pid == 0) {
            printf("---child, my parent= %d, going to sleep 10s\n", getppid());
            sleep(20);
            printf("-------------child die--------------\n");
            exit(77);
    } else if (pid > 0) {
        while (1) {
            printf("I am parent, pid = %d, myson = %d\n", getpid(), pid);

            wpid = wait(&status);
            if (wpid == -1) {
                perror("wait error");
                exit(1);
            }

            if (WIFEXITED(status)) {  //为真说明子进程正常结束
                printf("child exit with %d\n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) { //为真说明子进程被信号终止(异常)
                printf("child is killed by %d\n", WTERMSIG(status));
            }

            sleep(1);
        }
    } else {
        perror("fork");
        return 1;
    }

    return 0;
}

pid_t wit(int *status); 成功:清理掉的子进程ID;失败:-1(没有子进程)

当进程终止时,操作系统的隐式回收进制会:

  1. 关闭所有的文件描述符;
  2. 释放用户空间的内存;

内核的PCB仍存在。其中保存该进程的退出状态。(正常终止—>推出值;异常退出—>终止信号)

可使用wait函数传出参数status来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可以分为以下三组:

  1. WIFEXITED(status) 为非0 à 进程正常结束
    WEXITSTATUS(status)如上宏为真,使用此宏à获取进程的退出状态(exit参数)
  2. WIFSIGNALED(status)为非0 à 进程异常终止
    WTERMSIG(status)如上宏为真,使用此宏 à 取得使进程终止的那个信号的编号
/***
wait1.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, wpid;

    pid = fork();

    if(pid == -1){
        perror("fork error");
        exit(1);
    } else if(pid == 0){        //son
        printf("I'm process child, pid = %d\n", getpid());
        sleep(7);                //困了...
    } else {
lable:
        wpid = wait(NULL);        //死等!!!
        if(wpid == -1){
            perror("wait error");
            goto lable;
        }
        printf("I'm parent, I catched child process,"
                "pid = %d\n", wpid);
    }

    return 0;
}
/***
wait2.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, wpid;
    int status;

    pid = fork();

    if(pid == -1){
        perror("fork error");
        exit(1);
    } else if(pid == 0){        //son
        printf("I'm process child, pid = %d\n", getpid());
#if 1
        execl("./abnor", "abnor", NULL);
        perror("execl error");
        exit(1);
#endif
        sleep(1);                
        exit(10);
    } else {
        //wpid = wait(NULL);    //传出参数
        wpid = wait(&status);    //传出参数

        if(WIFEXITED(status)){    //正常退出
            printf("I'm parent, The child process "
                    "%d exit normally\n", wpid);
            printf("return value:%d\n", WEXITSTATUS(status));

        } else if (WIFSIGNALED(status)) {    //异常退出
            printf("The child process exit abnormally, "
                    "killed by signal %d\n", WTERMSIG(status));
                                        //获取信号编号
        } else {
            printf("other...\n");
        }
    }

    return 0;
}

wait(status):

                     返回:成功:pid  失败 -1

                     status:传出参数

                     1: 阻塞等待子进程

                     2: 回收子进程资源

                     3:    获取子进程结束状态:1)WIFEXITED()真

                                                                      WEXITSTATUS()获取子进程退出状态

                                                               2)WIFSIGNALED() 真

                                                                      WTERMSIG()获取导致子进程终止的信号的                                                                                           编码

原文地址:https://www.cnblogs.com/wanghao-boke/p/11311799.html