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()獲取導致子進程終止的信號的                                                                                           編碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM