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信号,故回收一次。子进程回收不完全。

  • 相关阅读:
    把握人生12种财富:让商人更自信
    英语谚语的汉译
    心胸有多大,事业才可能有多大
    想成领袖?先瞄准老板身边的位置
    绝对挑战:如何来提高自己的影响力?
    送给创业的朋友:落入坑洞的猎人
    跨越危机,塑造完美的职业生涯(三)
    如果一个男人真的爱你
    跨越危机,塑造完美的职业生涯(一)
    来自最伟大推销员的成功金句
  • 原文地址:https://www.cnblogs.com/lr1402585172/p/10563642.html
Copyright © 2011-2022 走看看