Linux模拟实现僵尸进程
发布时间:2021-04-26 14:59:14
Linux模拟实现僵尸进程
Z(zombie)-僵尸进程
僵死状态(Zombies) 是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码是就会产生僵尸进程。
僵尸进程会以终止状态保存在进程表中,并且会一直等待父进程读取退出状态代码。
所以,只要子进程退出,父进程还在执行,但父进程没有读取子进程状态,子进程进入Z状态
模拟实现僵尸进程
//模拟实现僵尸进程
int main()
{
pid_t pid;
pid = fork();
if(pid == -1)
{
perror("创建失败");
}
if(pid == 0)//孩子进程
{
sleep(3);
printf("孩子进程死亡\n");
}
else if(pid >0)//父进程
{
int times = 10;
while(times--)
{
printf("父进程:%d\n",times);
sleep(1);
}
printf("父进程死亡\n");
}
return 0;
}
测试结果
整个程序的调用过程如上,分别在1,2,3处调用了查看进程命令,1处表示程序正常执行,2处表示孩子进程已死亡,变成孤儿进程,3处表示父进程死亡并退出。
这是第一次查看进程的结果,红色的方框表示本进程的PID,第一个黄色的方框表示父进程的PID,第二个黄色的框表示进程名,由图可知,第二个进程的PID为3340,他的父进程为3339,恰好是第一个进程的PID,由此可知第二个进程是第一个进程的子进程,这时父子进程同时在运行。
此时表示孩子进程已死亡,但是父进程还在运行,子进程成为僵尸进程
最后父进程退出,系统回收资源,并将子进程的资源同时回收,进程消失。
僵尸进程的产生
一个进程调用exit命令结束自己生命的时候,其实它并没有真正的被销毁,而是留下一个称为“僵尸进程”的数据结构。这时它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置(它的内核栈还驻留在内存中),记载该进程的退出状态等有用的信息供其它进程收集。进程的状态变成EXIT_ZOMBIE,并且向父进程发送SIGCHLD信号,Linux默认是忽略该信号的,父进程可以显示安装该信号,在信号处理函数中调用wait或waitpid函数等待子进程结束并将其彻底清除。如果父进程没有这么做的话,子进程就沦为僵尸进程了。但是在父进程死掉后,它的所有进程都会过继给init进程,init进程会周期性的去调用wait系统调用来清除它的僵尸孩子。
僵尸进程的危害
少数的僵尸进程并不会对系统的性能有什么影响,但是由于Linux系统对运行的进程数量是有限制的,所以如果产生的僵尸进程过多,占用了可用的进程号,这将会导致新的进程无法生成。
怎么避免僵尸进程
(1)创建进程的时候调用两次fork,而且使紧跟的子进程直接退出,这样孙子进程成为孤儿进程,init进程将负责清除这个孤儿进程。
(2)在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN,这样内核在子进程结束时不会产生僵尸进程。在SVR4中,如果调用signal或sigset将SIGCHLD的配置设置为忽略,也不会产生僵尸进程。
(3)调用wait或waitpid等待子进程结束,收集僵尸进程留下的信息,同时使僵尸进程彻底消失。
(注:不能使用kill 后接SIGKILL信号这样的命令像杀死普通进程一样杀死僵尸进程,因为僵尸进程是已经死掉的进程,它不能再接收任何信号。)
想要了解更多软件相关知识、提升自我,就来盛图科技吧!
- 上一篇:软件测试的基本问题
- 下一篇:OpenCV是什么?