• SIGCHLD


    SIGCHLD的产生条件

      子进程终止时

      子进程接收到SIGSTOP信号停止时

      子进程处在停止态,接受到SIGCONT后唤醒时

    借助SIGCHLD信号回收子进程

    子进程结束运行其父进程会收到SIGCHLD信号该信号的默认处理动作是忽略可以捕捉该信号在捕捉函数中完成子进程状态的回收

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <signal.h>
    
    void sys_err(char *str)
    {
        perror(str);
        exit(1);
    }
    void do_sig_child(int signo)
    {
        int status;    pid_t pid;
        while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
            if (WIFEXITED(status))
                printf("child %d exit %d
    ", pid, WEXITSTATUS(status));
            else if (WIFSIGNALED(status))
                printf("child %d cancel signal %d
    ", pid, WTERMSIG(status));
        }
    }
    int main(void)
    {
        pid_t pid;    int i;
        for (i = 0; i < 10; i++) {
            if ((pid = fork()) == 0)
                break;
            else if (pid < 0)
                sys_err("fork");
        }
        if (pid == 0) {    
            int n = 1;
            while (n--) {
                printf("child ID %d
    ", getpid());
                sleep(1);
            }
            return i+1;
        } else if (pid > 0) {

          //这里还应对SIGCHLD进行阻塞  防止父进程SIGCHLD还未注册完成子进程就已经死亡
    struct sigaction act; act.sa_handler = do_sig_child; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, NULL);   //解除阻塞 while (1) { printf("Parent ID %d ", getpid()); sleep(1); } } return 0; }

    上述代码若将do_sig_child(),SIGCHLD信号处理函数改为:

    void do_sig_child(int signo)
    {
        int status;    pid_t pid;
        if((pid = waitpid(0, &status, WNOHANG)) > 0) {  //将while改为if
            if (WIFEXITED(status))
                printf("child %d exit %d
    ", pid, WEXITSTATUS(status));
            else if (WIFSIGNALED(status))
                printf("child %d cancel signal %d
    ", pid, WTERMSIG(status));
        }
    }

    此写法会导致子进程回收不完全,原因:在执行信号处理函数时,多个子进程同时死亡,产生多个SIGCHLD信号。但由于函数正在执行故屏蔽SIGCHLD,但执行完成后未决信号集中只记录一次SIGCHLD信号,故回收一次。子进程回收不完全。

  • 相关阅读:
    docker运行爬虫代码
    python语法之流程控制(if while for)
    python基本数据类型
    python基本运算符
    python用户交互与格式化输出
    jieba模块基本介绍
    wordcloud库基本介绍
    计算机基础之编程语言
    计算机基础
    python入门之流程控制
  • 原文地址:https://www.cnblogs.com/lr1402585172/p/10563642.html
Copyright © 2020-2023  润新知