解决避免僵死进程的问题
2013-03-09 08:44
204 查看
怎样产生僵尸进程的:
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程
是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退
出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信
号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。
Linux系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会导致新的进程无法生成。这就是僵尸进程对系统的最大危害。
知道了僵尸进程产生的原因后,就很容易清除僵尸进程了。
避免僵尸进程的出现的一种办法是父进程调用wait、waitpid等待子进程结束(即对其进行回收),但这样做有一个弊端就是在子进程结束前父进程会一直阻塞,不能做任何事情。另外一种更好的方法就是调用两次fork函数。
源代码如下:
产生僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char* argv[])
{
while(1)
{
pid_t chi = fork();
if(chi == 0)
{
execl("/bin/bash","bash","-c","ls",NULL);
}
sleep(2);
}
}
调用两次fork函数。避免僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(){
pid_t pid;
if((pid = fork()) < 0)
{ //创建子进程
perror("fork");
}
else if(pid == 0)//子进程1
{
if((pid = fork()) < 0)//由子进程1创建子进程2
{
perror("fork");
}
else if(pid > 0)
{
printf(" child,parent pid = %d\n",getppid());
exit(0); //子进程1结束
}
else//子进程2
{
printf("second child,parent pid = %d\n",getppid()); //打印子进程2的父进程
sleep(30);
exit(0);
}
}
else //父进程
{
/* do something else*/
waitpid(0,NULL,0);//收集子进程1结束
sleep(60);
}
return 0;
}
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程
是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退
出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信
号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。
Linux系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会导致新的进程无法生成。这就是僵尸进程对系统的最大危害。
知道了僵尸进程产生的原因后,就很容易清除僵尸进程了。
避免僵尸进程的出现的一种办法是父进程调用wait、waitpid等待子进程结束(即对其进行回收),但这样做有一个弊端就是在子进程结束前父进程会一直阻塞,不能做任何事情。另外一种更好的方法就是调用两次fork函数。
源代码如下:
产生僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char* argv[])
{
while(1)
{
pid_t chi = fork();
if(chi == 0)
{
execl("/bin/bash","bash","-c","ls",NULL);
}
sleep(2);
}
}
调用两次fork函数。避免僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(){
pid_t pid;
if((pid = fork()) < 0)
{ //创建子进程
perror("fork");
}
else if(pid == 0)//子进程1
{
if((pid = fork()) < 0)//由子进程1创建子进程2
{
perror("fork");
}
else if(pid > 0)
{
printf(" child,parent pid = %d\n",getppid());
exit(0); //子进程1结束
}
else//子进程2
{
printf("second child,parent pid = %d\n",getppid()); //打印子进程2的父进程
sleep(30);
exit(0);
}
}
else //父进程
{
/* do something else*/
waitpid(0,NULL,0);//收集子进程1结束
sleep(60);
}
return 0;
}
相关文章推荐
- 进程(程序)僵死问题解决方法
- 前端笔试题阿里篇之二--如何避免闭包,以及解决闭包问题
- linux避免僵死进程方法总结
- 解决”dllhost进程消耗cpu 100%的问题
- 关于windebug查询进程中各个线程占用cpu时间,解决CPU占用很大问题
- [置顶] 解决项目中不同进程中使用SharedPreferences存取数据不同步的问题
- 避免linux系统调用fork后产生僵死进程
- Dokcer 解决docker容器或者docker宿主机进程重启 IP地址丢失问题
- 解决yum进程被占用的问题
- 关于IIS服务启动失败的问题:“IIS提示‘另一个程序正在使用此文件,进程无法访问’”,的解决方法
- 避免僵死进程
- 解决crond引发大量sendmail、postdrop进程问题
- [解决]VS2010尝试设置 IDE 的进程内编译器的“References”参数时出现问题。对 COM 组件的调用
- 解决MySQL进程无法启动的问题
- 多进程同时访问文件并发问题解决方法
- epoll在多进程下产生的“惊群”现象——如何避免——多进程因为文件描述符继承问题导致
- 记一次解决mysql进程数居高不下的问题
- 避免使用count(*)获得表的记录数,解决其延迟问题
- Android安卓关于避免按钮快速多次点击问题解决办法
- 如何解决443端口被System进程占用,导致https访问只能带着端口号的问题