首页 > 代码库 > Linux下异步回收子进程
Linux下异步回收子进程
背景
我们知道,当一个进程fork出子进程后,没有对子进程进行回收,那么子进程运行完之后的状态会变为僵尸进程.
我们可以通过wait和waitpid来回收子进程,防止僵尸进程的出现.
但是wait和waitpid,要么以阻塞方式运行,要么以轮询方式运行,都极大的占用了CPU资源.
本文将介绍,父进程如何通过异步操作回收子进程!
原理
在每个子进程运行完成之后,都会向父进程发出SIGCHLD信号.而在默认情况下,父进程会忽略掉该信号.因此,我们只需要对SIGCHLD信号进行捕捉,即可异步对子进程进行回收.
核心代码1
void waitChild1(int sig){ int status = 0; if(waitpid(-1,&status,WNOHANG)>0){ printf("the child exit status is %d\n",WEXITSTATUS(status)); }else{ printf("failure!\n"); } }
因此,我们通过waitpid,对所有产生SIGCHLD信号的子进程都进行回收.
好像很简单的样子嘛!!!
对的,就是这么简单!
但是上述代码存在BUG,如果存在很多子进程都同时退出,那么就会同时向父进程发送信号.
而我们知道,由于受到位图的限制,常规信号出现多次时,只计算一次.因此,如果同时存在子进程出现时,以上代码肯定不能把所有子进程都回收掉!
所以,我们需要对代码进行加强!!!!
升级版核心代码
void waitChild2(int sig){ int status = 0; pid_t pid = 0; while((pid = waitpid(-1,&status,WNOHANG)) >0){ printf("%d‘s exit status is %d\n",pid,WEXITSTATUS(status)); } }
正如上述代码,改动的其实很简单,只需把if改成while即可!
完整版代码
//////////////////////////////////// //文件说明:wait.c //作者:高小调 //创建时间:2017年06月27日 星期二 20时45分16秒 //开发环境:Kali Linux/g++ v6.3.0 //////////////////////////////////// #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h> #include<stdlib.h> void waitChild1(int sig){ int status = 0; if(waitpid(-1,&status,WNOHANG)>0){ printf("the child exit status is %d\n",WEXITSTATUS(status)); }else{ printf("failure!\n"); } } void waitChild2(int sig){ int status = 0; pid_t pid = 0; while((pid = waitpid(-1,&status,WNOHANG)) >0){ printf("%d‘s exit status is %d\n",pid,WEXITSTATUS(status)); } } int main(){ signal(SIGCHLD,waitChild2); int pid = fork(); if(pid == 0){ //child printf("i am child,my pid is %d\n",getpid()); exit(1); } pid = fork(); if(pid == 0){ //child printf("i am child,my pid is %d\n",getpid()); exit(1); } pid = fork(); if(pid == 0){ //child printf("i am child,my pid is %d\n",getpid()); exit(1); } pid = fork(); if(pid == 0){ //child printf("i am child,my pid is %d\n",getpid()); exit(1); } while(1){ printf("i am father,my pid is %d\n",getpid()); sleep(5); } return 0; }
Linux下异步回收子进程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。