zoukankan      html  css  js  c++  java
  • 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信号,故回收一次。子进程回收不完全。

  • 相关阅读:
    第五周作业
    第四周作业
    第三周作业
    第二周作业
    Linux常用命令使用格式及实例
    总结linux哲学思想
    配置环境变量,实现执行history的时候可以看到执行命令的时间
    安装Centos7.6操作系统后,创建一个自己名字的用户名,并可以正常登陆
    各系列的Linux发行版及不同发行版之间的联系与区别
    python2使用Tkinter制作GUI内嵌matplotlib时,找不到NavigationToolbar2Tk的问题
  • 原文地址:https://www.cnblogs.com/lr1402585172/p/10563642.html
Copyright © 2011-2022 走看看