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