Linux下子进程的异步等待

通过wait函数或者waitpid函数可以清理僵尸进程,父进程可以通过两种方式等待子进程,一种是阻塞方式,另一种是非阻塞方式,而不管是那种方式,父进程都做不到完全不理会子进程而去完成自己的动作,即子进程不能达到异步等待的目的。
1、关于SIGCHLD信号

子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程就可以进行自己的动作而不必管理子进程,子进程只需要在退出时通知父进程,父进程在信号处理函数中调用wait函数来清理子进程即可。

我们可以自定义handler函数捕捉SIGCHLD信号并进行处理。

下面是一个信号捕捉的小程序:

在这个程序中,我们自定义了子进程在退出时打印信号编码,可以看到子进程退出时发送给父进程的是17号信号,即SIGCHLD

 1 #include<stdio.h>

 2 #include<sys/types.h>

  3 #include<signal.h>
  4 #include<stdlib.h>
  5 
  6 void handler(int signo)
  7 {
  8     printf("sig:%d,id:%d\n",signo,getpid());
  9 }
 10 
 11 int main()
 12 {
 13     int i=0;
 14     for(i=0;i<32;i++)
 15     {
 16         signal(i,handler);
 17     }
 18     pid_t id=fork();
 19     if(id==0)
 20     {
 21         sleep(2);
 22         printf("i am child");
 23         exit(1);
 24     }
 25     else{
 26         sleep(5);
 27         printf("i am father");
 28     }
 29     return 0;
 30 }
 31 


2、关于子进程的异步等待

父进程在等待时可以选择异步等待,即在等待的同时做自己的事情,是非阻塞等待

利用waitpid函数,将参数设置为WNOHANG,若由pid指定的子进程并不是立即可用的,则waitpid不阻塞,即此时以非阻塞方式(轮询式访问的必要条件)等待子进程,并且返回0。 

下面是一个例子:

  1 #include<stdio.h>
  2 #include<signal.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 void handler(int signo)
  6 {
  7     pid_t id;
  8     while(1)
  9     {
 10         switch(id==waitpid(-1,NULL,WNOHANG))
 11         {
 12             case 0:
 13             case 1:
 14                 return;
 15             default:
 16                 printf("wait success!%d\n",id);
 17                 break;
 18         }
 19     }
 20 }
 21 int main()
 22 {
 23     signal(SIGCHLD,handler);
 24     pid_t id=fork();
 25     if(id==0){//child
 26         sleep(5);
 27         printf("i am child:%d\n",getpid());
 28         exit(1);
 29     }
 30     else
 31     {
 32         while(1){
 33             printf("i am father, doing my thing!\n");
 34             sleep(1);
 35         }
 36     }
 37 }


从运行结果可以看出,子进程在sleep时父进程并没有堵塞等待,而是做自己的事情,知道子进程退出。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值