SIGCHLD的產生條件
子進程終止時
子進程接收到SIGSTOP信號停止時
子進程處在停止態,接受到SIGCONT后喚醒時
借助SIGCHLD信號回收子進程
子進程結束運行,其父進程會收到SIGCHLD信號。該信號的默認處理動作是忽略。可以捕捉該信號,在捕捉函數中完成子進程狀態的回收。
/*** sigchild.c ***/ #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\n", pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf("child %d cancel signal %d\n", 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\n", getpid());sleep(1);}return i+1;} else if (pid > 0) {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\n", getpid());sleep(1);}}return 0; }
?
/*** my_sigchild.c ***/ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<errno.h> #include<sys/types.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\n",pid,WEXITSTATUS(status));else if(WIFSIGNALED(status)){printf("child %d cancel signal %d\n",pid,WTERMSIG(status));}} }int main() {pid_t pid;int i;for(i = 0; i < 10; i++){if((pid = fork()) == 0){break;}else if(pid < 0){ sys_err("fork");} }if(0 == pid){int n = 1;while(n--){printf("child ID %d\n",getpid());sleep(1);}return i+1;}else if(pid > 0){struct sigaction act;act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);while(1){printf("Parent ID %d\n",getpid());sleep(1); }}return 0; }
?
分析該例子。結合 17)SIGCHLD 信號默認動作,掌握父使用捕捉函數回收子進程的方式。????????????? 【sigchild.c】
?????? 如果每創建一個子進程后不使用sleep可以嗎?可不可以將程序中,捕捉函數內部的while替換為if?為什么?
????? if ((pid = waitpid(0, &status, WNOHANG)) > 0) { ... }
????? 思考:信號不支持排隊,當正在執行SIGCHLD捕捉函數時,再過來一個或多個SIGCHLD信號怎么辦?