Linux日常——信号(4)子进程的异步等待方式

来源:互联网 发布:zepto.js鼠标滑动事件 编辑:程序博客网 时间:2024/06/05 23:01

SIGCHLD信号

1.进程等待的方式:
阻塞,非阻塞,异步
2.⽤wait和waitpid函数清理僵⼫进程。
⽗进程可以阻塞等待⼦进程结束,也可以⾮阻塞地查询是否有⼦进程结束等待清理(也就是轮询的⽅式)。
采⽤第⼀种⽅式,⽗进程阻塞了就不能处理⾃⼰的⼯作了;
采⽤第⼆种⽅式,⽗进程在处理⾃⼰的⼯作的同时还要记得时不时地轮询⼀ 下,程序实现复杂。
3.⼦进程在终⽌时会给⽗进程发SIGCHLD信号,该信号的默认处理动作是忽略,⽗进程可以⾃定义SIGCHLD信号的处理函数,这样⽗进程只需专⼼处理⾃⼰的⼯作,不必关⼼⼦进程了,⼦进程终⽌时会通知⽗进程,⽗进程在信号处理函数中调⽤wait清理⼦进程即可。

//实现单进程退出时向父亲发送17号信号SIGCHLD#include<stdio.h>#include<signal.h>#include<stdlib.h>void handler(int sig){    printf("father can get a sig:%d \n",sig);}int main(){    signal(SIGCHLD,handler);    pid_t id=fork();    if(id==0)    {        //child         printf("i'm child!:%d,myfather is %d\n",getpid(),getppid());        sleep(4);        exit(2);    }    else{        //father        printf("I'm daddy,I'm doing father's things\n");        waitpid(-1,NULL,0);        //父进程阻塞的等待子进程结束    }}

运行结果:
这里写图片描述

父进程等待子进程的异步版本

#include<stdio.h>#include<signal.h>#include<stdlib.h>void handler(int sig){      // printf("father can get a sig:%d from %d\n",sig,getpid());   do{    pid_t ret=waitpid(-1,NULL,WNOHANG);    //waitpid返回要等待的进程的pid,-1表示可以回收任意进程    //WNOHANG 若pid指定的子进程没有结束,则waitpid()函数返回0,    //不予以等待。若结束,则返回该子进程的ID,使父进程非阻塞等待。     if(ret>0)    {        printf("wait success!pid:%d\n",ret);    }    else    {        printf("wait failed!\n");        break;    }   }while(1);}int main(){        signal(SIGCHLD,handler);        pid_t id=fork();        if(id==0)        {          //child            printf("i'm child!:%d,myfather is %d\n",getpid(),getppid());            sleep(4);            exit(1);         }         else         {              //father                       while(1)           {           //将等待函数放进信号处理函数中,这样父进程就可以安心到的做自己的是,只需要在信号发出时回收进程就行。                printf("I'm daddy,I'm doing father's things\n");                sleep(1);            }          }    return 0; }

运行结果:
这里写图片描述
事实上,由于UNIX 的历史原因,要想不产⽣僵⼫进程还有另外⼀种办法:
⽗进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的⼦进程在终⽌时会⾃动清理掉,不 会产⽣僵⼫进程,也不会通知⽗进程。系统默认的忽略动作和⽤户⽤sigaction函数⾃定义的忽略 通常是没有区别的,但这是⼀个特例。此⽅法对于Linux可⽤,但不保证在其它UNIX系统上都可用。

原创粉丝点击