标签:style blog class code java c
关于如何避免僵尸进程。其实方法很多。有很多现成的解决方案。这里给出一个简单的方案。以及背后思考的过程。
设想一种最简单的http服务器:
伪代码:
当接收到一个tcp请求的时候.
fork 一个子进程去做工作。
主进程依旧在监听下面要来的请求。
这个模型实际上会导致。因为fork出来的子进程没有回收,并且父进程一直存在没有结束。导致越来越多的僵尸进程出现。
都知道子进程结束的时候会发一个sigchld信号给父进程。于是改进成增加一行代码:
signal(SIGCHLD,deal_signal);
void deal_signal()
{
wait(NULL);
}
但是这样做。依旧会有大量的僵尸进程存在。因为如果sigchid信号不断的发往 主进程。主进程是不会维护一个队列去缓存这些信号的。
而是 直接把这些信号全部丢弃掉。从而导致我们无法避免僵尸进程的存在。
百度一下 发现很多答案都是要这么写
void deal_signal()
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
经过测试 这样写可以避免僵尸进程.因为这里 的waitpid在一个循环内。也就是说 如果有信号被丢弃。但是因为信号被丢弃 但是进程还在。
所以这个循环会一直去寻找子进程 一直到所有子进程全部被回收为止。
但是问题就出在这。
既然上面的解决方案的key是因为while。哪我们能不能写成while(wait(NULL)>0)来避免僵尸进程呢。
为了证明这个问题。我们写代码来测试一下。
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> int main(int argc, char const *argv[]) { int i; pid_t pc; void deal_signal(); signal(SIGCHLD,deal_signal); for (i = 0; i < 100; ++i) { pc=fork(); switch(pc) { case 0: printf(" child process is %d\n", getpid()); break; default: printf(" father proces is %d\n",getpid() ); continue; } //用来保证所有的子进程直接退出 而不是继续循环 if(pc==0) break; } //这里保证 如果是父进程那么就一直阻塞。 //因为你如果不阻塞这个父进程 在shell里面跑这个程序 会立即执行完毕 //那么主进程就结束了 所以你永远也check不到有僵尸进程的存在 //因为当主进程结束的时候 那些子进程的父进程就变成了init进程 if (pc>0) { while(1) { } } return 0; }
在终端1 上面运行这个程序
然后在终端2 上面 输入命令
ps -A -ostat,ppid,pid | grep -e ‘^[Zz]‘
你会发现 可以看到 我们代码生成出来的那些僵尸进程了。
于是我们更改代码:
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> int number=0; int main(int argc, char const *argv[]) { int i; pid_t pc; void deal_signal(); signal(SIGCHLD,deal_signal); for (i = 0; i < 100; ++i) { pc=fork(); switch(pc) { case 0: printf(" child process is %d\n", getpid()); break; default: printf(" father proces is %d\n",getpid() ); continue; } if(pc==0) break; } if (pc>0) { while(1) { } } return 0; } void deal_signal() { while(wait(NULL)>0) { number++; printf("%d\n", number); } }
这个时候 我们再运行一次程序。并且在另外一个终端上面 运行命令
就会发现 是找不到僵尸进程的。
so 实际上 while(wait(NULL)>0)
这种写法 不但有效 而且更加简单方便理解。
关于如何有效避免僵尸进程的一种探索。(动手写自己的http服务器),布布扣,bubuko.com
关于如何有效避免僵尸进程的一种探索。(动手写自己的http服务器)
标签:style blog class code java c
原文地址:http://www.cnblogs.com/punkisnotdead/p/3724554.html