SIGCHLD信号

Posted Arlenmbx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SIGCHLD信号相关的知识,希望对你有一定的参考价值。

SIGCHLD的产生条件

1、子进程终止时 
2、子进程接收到SIGSTOP信号停止时 
3、子进程处在停止态,接受到SIGCONT后唤醒时

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <errno.h>
  5 #include <sys/types.h>
  6 #include <sys/wait.h>
  7 #include <signal.h>
  8 
  9 void sys_err(char *str)
 10 {
 11     perror(str);
 12     exit(1);
 13 }
 14 void do_sig_child(int signo)
 15 {
 16     int status;
 17     pid_t pid;
 18     while ((pid = waitpid(0, &status, WNOHANG)) > 0)
 19     {
 20         if (WIFEXITED(status))
 21             printf("child %d exit %d\n", pid, WEXITSTATUS(status));
 22         else if (WIFSIGNALED(status))
 23             printf("child %d cancel signal %d\n", pid, WTERMSIG(status));
 24     }
 25 }
 26 int main(void)
 27 {
 28     pid_t pid;
 29     int i;
 30 
 31     for (i = 0; i < 10; i++) 
 32     {
 33         if ((pid = fork()) == 0)
 34         break;
 35         else if (pid < 0)
 36             sys_err("fork");
 37     }
 38 
 39     if (pid == 0)
 40     {
 41         int n = 18;
 42         while (n--)
 43         {
 44             printf("child ID %d\n", getpid());
 45             sleep(1);
 46         }
 47         return i;
 48     }
 49     else if (pid > 0)
 50     {
 51         //先设置捕捉
 52         //再解除对SIGCHLD的阻塞
 53         struct sigaction act;
 54         act.sa_handler = do_sig_child;//捕捉函数在上面
 55         sigemptyset(&act.sa_mask);
 56         act.sa_flags = 0;
 57         sigaction(SIGCHLD, &act, NULL);//当SIGCHLD信号到达是调用信号处理函数
 58 
 59         while (1)
 60         {
 61             printf("Parent ID %d\n", getpid());
 62             sleep(1);
 63         }
 64     }
 65     return 0;
 66 }
 67 
 68 
 69 
 70 执行结果:
 71 child ID 4170
 72 child ID 4171
 73 child ID 4169
 74 child ID 4172
 75 child ID 4168
 76 child ID 4166
 77 child ID 4165
 78 child ID 4164
 79 child ID 4163
 80 child ID 4170
 81 Parent ID 4162
 82 child ID 4167
 83 child ID 4171
 84 child ID 4169
 85 child ID 4172
 86 child ID 4168
 87 child ID 4166
 88 child ID 4165
 89 child ID 4164
 90 child ID 4163
 91 Parent ID 4162
 92 child 4167 exit 4
 93 child 4170 exit 7
 94 Parent ID 4162
 95 child 4169 exit 6
 96 child 4171 exit 8
 97 Parent ID 4162
 98 child 4168 exit 5
 99 child 4172 exit 9
100 Parent ID 4162
101 child 4166 exit 3
102 Parent ID 4162
103 child 4165 exit 2
104 Parent ID 4162
105 child 4164 exit 1
106 Parent ID 4162
107 child 4163 exit 0
108 Parent ID 4162
109 Parent ID 4162
110 Parent ID 4162
111 ^C
pid_t waitpid(pid_t pid, int *status, int options)
    options
        WNOHANG
            没有子进程结束,立即返回
        WUNTRACED
            如果子进程由于被停止产生的SIGCHLD, waitpid则立即返回
        WCONTINUED
            如果子进程由于被SIGCONT唤醒而产生的SIGCHLD, waitpid则立即返回

    获取status
        WIFEXITED(status)
            子进程正常exit终止,返回真
                WEXITSTATUS(status)返回子进程正常退出值
        WIFSIGNALED(status)
            子进程被信号终止,返回真
                WTERMSIG(status)返回终止子进程的信号值
        WIFSTOPPED(status)
            子进程被停止,返回真
                WSTOPSIG(status)返回停止子进程的信号值
        WIFCONTINUED(status)
            子进程由停止态转为就绪态,返回真

 

以上是关于SIGCHLD信号的主要内容,如果未能解决你的问题,请参考以下文章

10.7 SIGCHLD定义

SIGCHLD信号

忽略SIGCHLD信号能避免僵尸进程吗

UNIX中system函数的实现为啥要阻塞SIGCHLD信号?

不可靠信号SIGCHLD丢失的问题

Linux学习信号——信号保存 | 信号处理 | 不可重入函数,volatile,SIGCHLD信号