避免产生僵尸进程的N种方法(zombie process)
2012-09-10 22:28
411 查看
认识僵尸进程
1、如果父进程先退出子进程自动被 init 进程收养,不会产生僵尸进程
2、如果子进程先退出
2.1 父进程 wait() 处理,则僵尸进程会被父进程清理
2.2 如果父进程不用 wait() 处理,则僵尸进程会在父进程退出之前一直存在。当然,父进程退出后,僵尸子进程会被 init 收养,init 进程会自动调用 wait() 处理。但是对于处理网络请求的服务器进程来说,父进程可能会一直存在,子进程处理完任务就退出,这种情况下会产生很多僵尸进程,这种场景就需要对僵尸进程的处理提高警惕了。
避免产生僵尸进程的5种方法
1、推荐方法:fock twice, 用孙子进程去完成子进程的任务(注意这种方法的使用情景)(http://blog.csdn.net/duyiwuer2009/article/details/7948040)2、wait(), 但是会使父进程阻塞
3、signal(SIGCHLD,SIG_IGN), 并不是所有系统都兼容
4、sigaction + SA_NOCLDWAIT, 并不是所有系统都兼容
5、推荐方法:在signal handler中调用 waitpid (下面的例子能说明用 waitpid 而不用 wait的原因),这样父进程不用阻塞
注意:每一种方法都有它适用的场合,比如方法 5 适用于 one-request-one-process 的网络服务器程序,而方法 1 则不适合。
关于对处理SIGCHLD或SIGCLD的讨论,APUE 10.7(http://infohost.nmt.edu/~eweiss/222_book/222_book.html) 是最权威最经典的,不过可能由于书出得较早,考虑了太多老系统,当时的系统对信号的处理还不是很完善,使得书中对这个问题的讨论显得相当复杂,但对于现在的系统,我们可以简化许多。
方法4的代码:
#include <signal.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; struct sigaction sa; /* prevent zombies */ sa.sa_handler = SIG_IGN; sa.sa_flags = SA_NOCLDWAIT; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } if( (pid = fork()) < 0 ) { exit(1); } else if(pid == 0) { sleep(10); exit(0); } sleep(20); return 0; }笔者所用系统的内核版本是2.6.38-8,方法3和方法4都支持
方法5的代码:
/** * Final (correct) version of sig_chld function that calls waitpid. * * UNIX Network Programming Volume 1, Third Edition, 5.9(Handling 'SIGCHLD' Signals) and 5.10 */ void sig_chld(int signo) { pid_t pid; int stat; while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0 ) { printf("child %d terminated\n", pid); } return; }Establishing a signal handler and calling wait from that handlerare insufficient for preventing zombies. The problem is that if five signals are generated before the signal handler is executed, the signal handler
is executed only one time becauseUnix signals are normally not queued(这种情况下只会产生一次"SIGCHLD"信号).
In this case, the signal handler is executed once, leaving four zombies.
The correct solution is to call waitpid
instead of wait, and we must specify theWNOHANGoption: This tells waitpid not to block if there are running children that have not yet terminated.
【参考资料】
UNIX Network Programming Volume 1, Third Edition, 5.9(Handling 'SIGCHLD' Signals) and 5.10
http://topic.csdn.net/u/20090911/16/5860C371-DBF9-440A-851B-C6AD26B6E480.html
http://baike.baidu.com/view/758736.htm
线程和进程的分离,http://blog.chinaunix.net/space.php?uid=317451&do=blog&id=92626
How do I get rid of zombie processes that persevere, http://www.faqs.org/faqs/unix-faq/faq/part3/section-13.html
http://www.ccur.com/isdfaq/How_do_I_avoid_creating_zombies.txt
相关文章推荐
- 避免产生僵尸进程的N种方法(zombie process)
- 僵尸进程的产生、危害及避免方法
- 僵尸进程是如何产生的?怎样避免僵尸进程的产生
- 【专题1】僵尸进程的产生和避免
- 僵尸进程(zombie)以及避免方法
- Linux的僵尸进程产生原因及解决方法
- Linux下如何避免僵尸进程的产生
- 为何要fork()两次来避免产生僵尸进程?
- 僵尸进程的产生与避免
- Linux下的僵尸进程及避免方法
- linux僵尸进程产生的原因以及如何避免产生僵尸进程
- Linux的僵尸进程产生原因及解决方法
- Linux下多进程避免僵尸进程的方法
- linux僵尸进程产生的原因以及如何避免产生僵尸进程
- Linux僵尸进程产生及如何避免
- Linux 僵尸进程产生及如何避免
- 为何要fork()两次来避免产生僵尸进程?
- linux下僵尸进程(Defunct进程)的产生与避免
- Linux 僵尸进程产生原因及解决方法
- linux僵尸进程产生的原因以及如何避免产生僵尸进程