【Linux系统编程】进程_01_进程基础API_05_僵尸进程,回收子进程wait&waitpid

wait & waitpid

  1. 功能:收集子进程的终止状态信息
  2. 原型
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
// 常用法:int wstatus;
// pid_t pid = wait(&wstatus);

// wait(&status) 等价于 waitpid(-1, &status, 0),但是能选等哪个进程死
  1. 参数
    1)int* wstatus
    2)pid
    3)option:0,一直等待;WNOHANG,不阻塞
  2. 返回值
    成功:返回终止子进程的 pid(waitpid:如果设置了 WNOHANG, 并且没有子进程的状态发生修改,返回 0)
    失败:返回-1,并会设置errno
  3. DO
// wait.c
#include <func.h>

void print_wstatus(int status) {
    if (WIFEXITED(status)) {
        int exit_code = WEXITSTATUS(status);
        printf("exit_code = %d", exit_code);
    } else if (WIFSIGNALED(status)) {
        int signo = WTERMSIG(status);
        printf("term_sig = %d", signo);
#ifdef WCOREDUMP
        if (WCOREDUMP(status)) {
            printf(" (core dump)");
        }
#endif
    }
    printf("\n");
}

int main(int argc, char* argv[]) {
    pid_t pid = fork();
    switch (pid) {
    case -1:
        error(1, errno, "fork");
    case 0:
        // 子进程
        printf("CHILD: pid = %d\n", getpid());
        // sleep(2);
        // return 123;
        // exit(96);
        //_exit(9);
        // abort();
        while (1);	// kill -SIGINT pid
    default: {
        // 母进程
        int status; // 保存子进程的终止状态信息,位图
        pid_t childPid = wait(&status); // 阻塞点:一直等待,直到有子进程终止
        if (childPid > 0) {
            printf("PARENT: %d terminated\n", childPid);
            print_wstatus(status);
        }
        exit(0);
    }
    }

    return 0;
}
// waitpid.c
#include <func.h>

void print_wstatus(int status) {
    if (WIFEXITED(status)) {
        int exit_code = WEXITSTATUS(status);
        printf("exit_code = %d", exit_code);
    } else if (WIFSIGNALED(status)) {
        int signo = WTERMSIG(status);
        printf("term_sig = %d", signo);
#ifdef WCOREDUMP
        if (WCOREDUMP(status)) {
            printf(" (code dump)");
        }
#endif
    }
    printf("\n");
}

int main(int argc, char* argv[]) {
    pid_t pid = fork();
    switch (pid) {
    case -1:
        error(1, errno, "fork");
    case 0:
        // 子进程
        printf("CHILD: pid = %d\n", getpid());
        // sleep(2);
        // return 123;
        // exit(96);
        // _exit(9);
        // abort();
        while (1);
    default: {
        // 母进程
        int status; // 保存子进程的终止状态信息,位图
        // 阻塞点:一直等待,直到有子进程终止
        pid_t childPid = waitpid(-1, &status, 0);   // 等价于wait(&status) 
        // pid_t childPid = waitpid(-1, &status, WNOHANG);  // 不阻塞
        if (childPid > 0) {
            printf("PARENT: %d terminated\n", childPid);
            print_wstatus(status);
        } else if (childPid == 0) {
            printf("PARENT: no child changed state\n");
        } else {
            error(1, 0, "waitpid");
        }
        exit(0);    
    }
    }

    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值