异步回收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
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
相关文章推荐
- 异步回收fork出的子进程(僵尸进程)
- 异步回收fork出的子进程(僵尸进程)
- fork两次如何避免僵尸进程
- [置顶] Linux高编之进程--------fork函数的同步与异步(兄弟子进程和父子孙进程示列)
- linux系统编程之进程(四):wait/waitpid函数与僵尸进程、fork 2 times
- fork两次如何避免僵尸进程
- fork两次如何避免僵尸进程收藏
- fork两次如何避免僵尸进程
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- 为什么fork()2次会避免产生僵尸进程
- Linux的进程,线程以及调度(fork与僵尸,内存泄漏,task结构体,停止状态与作业控制)
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- 调用 fork 两次避免僵尸进程
- 进程学习回顾---两次fork避免僵尸进程
- Unix通过fork两次避免僵尸进程
- linux 在线程中fork无法清除僵尸进程。
- fork两次如何避免僵尸进程收藏
- linux—fork的那些事(僵尸进程)
- fork() & 僵尸进程
- linux系统编程之进程(四):wait/waitpid函数与僵尸进程、fork 2 times