天天看點

SIGCHLD回收子程序

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;
}
           

繼續閱讀