一般的,父進程在生成子進程之后會有兩種情況,一種是父進程繼續(xù)去做別的事情,另一種是父進程啥都不做,一直在wait子進程退出.SIGCHLD信號就是為這第一種情況準(zhǔn)備的,它讓父進程去做別的事情,而只要父進程注冊了處理該信號的函數(shù),在子進程退出時就會調(diào)用該函數(shù),在該函數(shù)中又可以調(diào)用wait得到終止的子進程的狀態(tài)。處理信號的函數(shù)執(zhí)行完后,再繼續(xù)做父進程的事情.
也就是說,如果父進程在fork之后調(diào)用wait,就會阻塞,直到有一個子進程退出。 如果父進程在fork之前先signal(SIGCLD, sig_cld),即注冊了SIGCLD的信號處理函數(shù)。然后做自己的事情。當(dāng)子進程退出時,會給父進程發(fā)送一個SIGCLD信號。然后sig_cld函數(shù)就會執(zhí)行。可以在sig_cld函數(shù)中調(diào)用wait獲得子進程退出時的狀態(tài),并且此時wait不會阻塞。 當(dāng)sig_cld函數(shù)執(zhí)行完后,父進程又繼續(xù)做自己的事情。
#include<sys/wait.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h>
#include<sys/wait.h>
static void sig_cld(int);
int main() { pid_t pid; int status;
if(signal(SIGCLD,sig_cld) == SIG_ERR) { printf("signal error\n"); exit(-1); } if((pid = fork()) < 0) { printf("fork error\n"); exit(-1); } else if(pid == 0) { //child printf("%d fork a new child %d\n",getppid(),getpid()); sleep(1); _exit(19); } else { //parent int i,j; for(i=0;i<100;i++) { for(j=0;j<10000000;j++); printf("%d\n",i); } }
}
static void sig_cld(int signo) { pid_t pid; int status;
printf("SIGCLD received\n"); if((pid = wait(&status)) <0) { printf("wait error\n"); } printf("pid = %d\n",pid); }
|