SIGCHLD信号處理
子程序在暫停或提出時發送SIGCHLD信号,可以通過捕捉該信号來回收子程序
child_catch.c
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
void catch_sig(int num){
pid_t wpid=waitpid(-1,NULL,WNOHANG);
if(wpid>0){
printf("wait child %d ok\n",wpid);
}
}
int main(int argc,char * argv[])
{
int i=0;
pid_t pid;
for(i=0;i<10;i++){
pid=fork();
if(pid==0){
break;
}
}
if(i==10){
struct sigaction act;
act.sa_flags=0;
sigemptyset(&act.sa_mask);
act.sa_handler=catch_sig;
sigaction(SIGCHLD,&act,NULL);
while(1){
sleep(1);
}
}else if(i<10){
printf("I am %d child,pid=%d\n",i,geipid());
sleep(i);
}
return 0;
}
child_catch.c
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
void catch_sig(int num){
pid_t wpid;
while((wpid=waitpid(-1,NULL,WNOHANG))>0){
printf("wait child %d ok\n",wpid);
}
}
int main(int argc,char * argv[])
{
int i=0;
pid_t pid;
//在建立子程序之前屏蔽SIGCHLD信号
sigset_t myset,oldset;
sigaddset(&myset,SIGCHLD);
//oldset保留現場,設定了SIGCHLD到阻塞信号集
sigprocmask(SIG_BLOCK,&myset,&oldset);
for(i=0;i<10;i++){
pid=fork();
if(pid==0){
break;
}
}
if(i==10){
sleep(2); //模拟注冊晚于子程序死亡
struct sigaction act;
act.sa_flags=0;
sigemptyset(&act.sa_mask);
act.sa_handler=catch_sig;
sigaction(SIGCHLD,&act,NULL);
//解除屏蔽
sigprocmask(SIG_SETMASK,&oldset,NULL);
while(1){
sleep(1);
}
}else if(i<10){
printf("I am %d child,pid=%d\n",i,geipid());
//sleep(i);
}
return 0;
}