posts - 297,  comments - 15,  trackbacks - 0

转载请注明:http://www.coder4.com/index.php /archives/151

首先特别感谢这篇文章给的启发!
http://hi.baidu.com/%D3%EA%BA%E7%D1%F4/blog/item/6490202aaba49193023bf633.html
对原作者表示敬意和膜拜!

fork()之后,非阻塞(异步)等待子进程(回收僵尸)。
fork()之后,子进程和父进程分叉执行,僵尸进程的产生是因为父进程没有给子进程“收尸”造成的,又可以根据危害程度分为下述两类:
总体来说:当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程。
(1)当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程,父进程结束后僵尸被init进程回收。
(2)如果子进程结束了,但是父进程始终没有结束,那么这个僵尸将一直存在,而且随着exec,僵尸越来越多。
如下面的代码,在父进程执行的5s内,子进程将为僵尸:

1 /*
2  * main.cc
3  *
4  *  Created on: 2009-12-3
5  *      Author: liheyuan
6  *    Describe:
7  *
8  *   Last Date: 2009-12-3
9  *   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一直等 待,不往下面的语句执行。

1 /*
2  * main.cc
3  *
4  *  Created on: 2009-12-3
5  *      Author: liheyuan
6  *    Describe:
7  *
8  *   Last Date: 2009-12-3
9  *   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用于设置处理信号量的规则(或跳转到的函数)

1 signal(SIGCHLD,handler);
2 void handler(int num)
3 {
4     //我接受到了SIGCHLD的信号啦
5     int status;
6     int pid = waitpid(-1,&status,WNOHANG);
7     if(WIFEXITED(status))
8     {
9         printf("The child exit with code %d",WEXITSTATUS(status));
10     }
11 }

 

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

1 /*
2  * main.cc
3  *
4  *  Created on: 2009-12-3
5  *      Author: liheyuan
6  *    Describe:
7  *
8  *   Last Date: 2009-12-3
9  *   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 }


posted on 2010-03-30 11:27 chatler 阅读(378) 评论(0)  编辑 收藏 引用 所属分类: Linux_Coding

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2010年3月>
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(10)

随笔分类(307)

随笔档案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感觉这个博客还是不错,虽然做的东西和我不大相关,觉得看看还是有好处的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新评论

阅读排行榜

评论排行榜