您的位置:首页 > 其它

异步回收fork出的子进程(僵尸进程)

2014-12-16 21:42 176 查看
http://blog.csdn.net/guzhouke19910920/article/details/7644989

fork()之后,非阻塞(异步)等待子进程(回收僵尸)。

fork()之后,子进程和父进程分叉执行,僵尸进程的产生是因为父进程没有给子进程“收尸”造成的,又可以根据危害程度分为下述两类:

总体来说:当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程。

(1)当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程,父进程结束后僵尸被init进程回收。

(2)如果子进程结束了,但是父进程始终没有结束,那么这个僵尸将一直存在,而且随着exec,僵尸越来越多。

如下面的代码,在父进程执行的5s内,子进程将为僵尸:

查看源代码

打印帮助

01 /*

02 * main.cc

03 *

04 * Created on: 2009-12-3

05 * Author: liheyuan

06 * Describe:

07 *

08 * Last Date: 2009-12-3

09 * CopyRight: 2009 @ ICT LiHeyuan

10 */

11

12 #include <stdio.h>

13 #include <stdlib.h>

14 #include <signal.h>

15 #include <unistd.h>

16

17 int main() {

18 //子进程的pid

19 int c_pid;

20 int pid;

21

22 if ((pid = fork())) {

23 //父进程

24 c_pid = pid;

25 printf("The child process is %d\n", c_pid);

26 sleep(5);

27 exit(0);

28 } else {

29 //子进程

30 printf("I 'm a child.\n");

31 exit(0);

32 }

33 }

如上面的代码,在父进程的5s内,子进程一直是僵尸!

因此,需要对僵尸进程进行回收,传统的回收方法是,使用wait()函数,等待子进程,wait()是阻塞模式的,当子进程没有结束之前,wait一直等待,不往下面的语句执行。

查看源代码

打印帮助

01 /*

02 * main.cc

03 *

04 * Created on: 2009-12-3

05 * Author: liheyuan

06 * Describe:

07 *

08 * Last Date: 2009-12-3

09 * CopyRight: 2009 @ ICT LiHeyuan

10 */

11

12 #include <stdio.h>

13 #include <stdlib.h>

14 #include <signal.h>

15 #include <unistd.h>

16 #include <sys/wait.h>

17

18 int main() {

19 //子进程的pid

20 int c_pid;

21 int pid;

22

23 if ((pid = fork())) {

24 //父进程

25 c_pid = pid;

26 printf("The child process is %d\n", c_pid);

27 //阻塞等待子进程

28 int status;

29 if ((pid = wait(&status)) != -1 && pid == c_pid) {

30 //成功回收子进程

31 printf("The child exit with %d\n", WEXITSTATUS(status));

32 fflush(stdin);

33 } else {

34 printf("wait() fail.\n");

35 }

36 printf("Now , The child has been exit , and I will sleep.\n");

37 sleep(20);

38 exit(0);

39 } else {

40 //子进程

41 printf("I 'm a child.\n");

42 sleep(5);

43 exit(0);

44 }

45 }

转载自:4号程序员

如上面的代码,在子进程执行5秒后,即被回收,在夫进程的20秒内,子进程已经被结束,不再是僵尸。

但是这种利用wait()阻塞等待的方法也有一定的缺陷,那就是父进程必须等待子进程,无法做其他事情,如何非阻塞的等待子进程呢?

man wait,查看NOTES章节,可以找到:

子进程退出的时候,会发送SIGCHLD信号,默认的POSIX不响应,所以,我们只需要把处理SIGCHLD的函数自己实现就OK了,怎么作呢?

signal用于设置处理信号量的规则(或跳转到的函数)

查看源代码

打印帮助

01 signal(SIGCHLD,handler);

02 void handler(int num)

03 {

04 //我接受到了SIGCHLD的信号啦

05 int status;

06 int pid = waitpid(-1,&status,WNOHANG);

07 if(WIFEXITED(status))

08 {

09 printf("The child exit with code %d",WEXITSTATUS(status));

10 }

11 }

OK,全部代码如下,注意父进程不要再用wait阻塞啦!

查看源代码

打印帮助

01 /*

02 * main.cc

03 *

04 * Created on: 2009-12-3

05 * Author: liheyuan

06 * Describe:

07 *

08 * Last Date: 2009-12-3

09 * CopyRight: 2009 @ ICT LiHeyuan

10 */

11

12 #include <stdio.h>

13 #include <stdlib.h>

14 #include <signal.h>

15 #include <unistd.h>

16 #include <sys/wait.h>

17

18 void handler(int num) {

19 //我接受到了SIGCHLD的信号啦

20 int status;

21 int pid = waitpid(-1, &status, WNOHANG);

22 if (WIFEXITED(status)) {

23 printf("The child %d exit with code %d\n", pid, WEXITSTATUS(status));

24 }

25 }

26

27 int main() {

28 //子进程的pid

29 int c_pid;

30 int pid;

31

32 signal(SIGCHLD, handler);

33

34 if ((pid = fork())) {

35 //父进程

36 c_pid = pid;

37 printf("The child process is %d\n", c_pid);

38

39 //父进程不用等待,做自己的事情吧~

40 for (int i = 0; i < 10; i++) {

41 printf("Do parent things.\n");

42 sleep(1);

43 }

44

45 exit(0);

46 } else {

47 //子进程

48 printf("I 'm a child.\n");

49 sleep(2);

50 exit(0);

51 }

52 }

转载请注明出处:http://www.coder4.com/index.php/archives/151
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: