一般的,父進程在生成子進程之后會有兩種情況,一種是父進程繼續去做別的事情,另一種是父進程啥都不做,一直在wait子進程退出.SIGCHLD信號就是為這第一種情況準備的,它讓父進程去做別的事情,而只要父進程注冊了處理該信號的函數,在子進程退出時就會調用該函數,在該函數中又可以調用wait得到終止的子進程的狀態。處理信號的函數執行完后,再繼續做父進程的事情.
也就是說,如果父進程在fork之后調用wait,就會阻塞,直到有一個子進程退出。 如果父進程在fork之前先signal(SIGCLD, sig_cld),即注冊了SIGCLD的信號處理函數。然后做自己的事情。當子進程退出時,會給父進程發送一個SIGCLD信號。然后sig_cld函數就會執行。可以在sig_cld函數中調用wait獲得子進程退出時的狀態,并且此時wait不會阻塞。 當sig_cld函數執行完后,父進程又繼續做自己的事情。
#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); }
|