码迷,mamicode.com
首页 > 其他好文 > 详细

signal之——异步回收机制

时间:2018-04-24 20:25:51      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:mask   amp   期望   char   include   nbsp   hang   else   err   

前言:回收子进程之前用了wait()和非阻塞模型,今天学了信号以后可以使回收机制更上一层楼,通过信号函数,父进程只需要做自己的事情,接收到信号后就触发信号函数。

信号处理函数可能会出现的bug:

  1.受到停止信号也会触发SIGCHLD信号,使wait阻塞;

  2.停止后继续也会触发信号,导致父进程阻塞;

  3.调用sigaction(),人为发送一个SIGCHLD信号也会使父进程阻塞;

  4.多个进程同时结束,可能造成回收不完全,产生僵尸进程(同中信号不排队);

解决方案的终极代码:

//异步回收子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

#define     NR         40

/*
 * bugs:如果多个进程同时结束 可能造成回收不完全 产生僵尸进程 (同种信号不排队)
 * 循环方式waitpid解决以上bugs
*/
void waitChild(int signo)
{
     pid_t pid;
     printf("a sig recv:%d\n",signo);
     if(signo!=SIGCHLD)  return;

     while(1)  //保证触发一次信号,回收所有结束的子进程
     {
         pid=waitpid(-1,NULL,WNOHANG|WUNTRACED);//保证非阻塞,以及停止不触发信号
         printf("wait child:%d\n",pid);

         if(pid==0||pid==-1)
                break;
     }
}


int main(void)
{
     pid_t pid;

#if 0
     //子进程结束或停止 或者从停止到继续 发生SIGCHLD信号
     if(signal(SIGCHLD,waitChild)==SIG_ERR)
     {
         perror("signal");
         return 2;
     }
#else
     struct sigaction  ac={.sa_handler=waitChild};//处理函数
     sigemptyset(&ac.sa_mask);//不期望屏蔽其它信号
     ac.sa_flags=SA_NOCLDSTOP;//进程停止时不发生SIGCHLD信号
     sigaction(SIGCHLD,&ac,NULL);
#endif //

     int i;
     for(i=0;i<NR;i++)
     {
        pid=fork();
        if(pid==-1)   return 1;//error
        else if(pid==0)//child
        {
            printf("%dth child <%d> start work.\n",i,getpid());
            sleep(3);
            printf("%dth child <%d> end   work.\n",i,getpid());
            exit(0);
        }
     }
     //parent
     while(1)
     {
         getchar();
         printf("parent working....\n");
     }

     return 0;
}

 

signal之——异步回收机制

标签:mask   amp   期望   char   include   nbsp   hang   else   err   

原文地址:https://www.cnblogs.com/edan/p/8933008.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!