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 ", pid, WEXITSTATUS(status)); 22 else if (WIFSIGNALED(status)) 23 printf("child %d cancel signal %d ", 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 ", 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 ", 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) 子进程由停止态转为就绪态,返回真