Linux下异步回收子进程

发布时间:2017-7-1 11:15:14编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"Linux下异步回收子进程 ",主要涉及到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;}


上一篇:其实,我只想安静的写写代码...
下一篇:svn 使用教程

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款