子進程執行完畢后,會向父進程發出 SIGCHLD信號 , 這段代碼實現的就是i,父進程接受到子進程 發出的SIGCHLD信號,實現對子進程進行回收,從而避免僵尸進程
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>void catch(int sigNum) {pid_t wpid;// 這里之所以寫成while循環的方式, // 是為了應對當多個子進程——同時——發出SIGCHLD信號的時候,主進程能夠// 將所有發出SIGCHLD信號的子進程回收掉while( (wpid = waitpid(-1, NULL, WNOHANG)) > 0) {printf("father wait son pid is %d\n", wpid);}
}int main() {// 因為主進程 在注冊 SIGCHLD信號處理的時候,子進程可能已經執行//完畢,子進程發出SIGCHLD信號的時候,早于主進程對SIGCHLD處理的注冊// 這時候首先 在主進程 ,設置 SIGCHLD為屏蔽信號(屏蔽信號集),這樣就影響了// 主進程的未決信號集,使主進程的未決信號集,SIGCHLD對應的位置為1,sigset_t myset, oldset;sigemptyset(&myset);sigaddset(&myset, SIGCHLD);sigprocmask(SIG_BLOCK, &myset, &oldset);pid_t pid;int i;for(i=0; i<10; ++i) {pid = fork();if(pid == 0) {break;}}if(i == 10) {// father// 模擬先讓子進程執行完畢,主進程再注冊 SIGCHLD信號處理函數sleep(2);struct sigaction act;act.sa_flags = 0;sigemptyset(&act.sa_mask);act.sa_handler = catch;sigaction(SIGCHLD, &act, NULL);// 當主進程注冊了 SIGCHLD的時候,將屏蔽信號集恢復,// 進而 ,主進程的未決信號集,SIGCHLD的那個,也會處理, 由1變為0,從而觸發 處理函數,回收子進程sigprocmask(SIG_SETMASK, &oldset, NULL);while (1) {sleep(1);}} else if(i < 10) {// sonprintf("I am son process pid is %d\n", getpid());}return 0;
}