如何产⽣⼀个僵⼫进程,以及如何避免产⽣僵⼫进程?
扇形僵⼫进程(Zombie)
如同⽣命体⼀般,进程也有开始和结束。
进程退出时会进⾏内核清理,释放进程所有的资源,这些资源包括内存资源、⽂件资源、信号量资源、共享内存资源,或者引⽤计数减⼀,或者彻底释放。
不过,进程的退出其实并没有将所有的资源完全释放,仍保留了少量的资源,⽐如进程的PID依然被占⽤着,不可被系统分配。此时的进程不可运⾏,事实上也没有地址空间让其运⾏(因为⼤部分资源已经被回收),进程进⼊僵⼫状态。
为什么进程退出之后不将所有的资源释放,反⽽保留了少量资源, 进⼊僵⼫状态呢?
看看僵⼫进程依然占有的系统资源,我们就能获得答案。
僵⼫进程依然保留的资源有进程控制块task_struct、内核栈等。这些资源不释放是为了提供⼀些重要的信息,⽐如进程为何退出,是收到信号退出还是正常退出,进程退出码是多少,进程⼀共消耗了多少系统CPU时间,多少⽤户CPU时间,收到了多少信号,发⽣了多少次上下⽂切换,最⼤内存驻留集是多少,产⽣多少缺页中 断?等等。这些信息总结了进程的⼀⽣。
如果没有这个僵⼫状态,进程的这些信息也会随之流逝,系统也将再也没有机会获知该进程的相关信息了。
因此进程退出后,会保留少量的资源,等待⽗进程前来收集这些信息。⼀旦⽗进程收集了这些信息之后(通过调⽤下⾯提到的 wait/waitpid 等函数),这些残存的资源完成了它的使命,就可以释放了,进程就脱离僵⼫状态,彻底消失了。
如何产⽣⼀个僵⼫进程?
制造⼀个僵⼫进程是⼀件很容易的事情,只要⽗进程调⽤fork创建⼦进程,⼦进程退出后,⽗进程如果不调⽤wait或waitpid来获取⼦进程的退出信息,⼦进程就会沦为僵⼫进程。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
支付宝自动续费怎么取消{
pid_t pid;
pid =fork();
if(pid <0)
{
/* 如果出错 */
printf("error occurred!\n");
老师名言}
else if(pid ==0)
{
/* ⼦进程 */
exit(0);
}
else
{
/* ⽗进程 */
/* 休眠 300秒 */
sleep(300);
/* 获取僵⼫进程的退出信息 */
wait(NULL);
}说明文的方法
return0;
}
上⾯的例⼦中⽗进程休眠300秒后才会调⽤wait来获取⼦进程的退出信息。⽽⼦进程退出之后就会变成僵⼫状态,成为⼀个僵⼫进程。直到⽗进程来获取退出信息,才彻底被释放。
清除僵⼫进程有以下两种⽅法:
1、⽗进程调⽤wait函数,为⼦进程“收⼫”。
2、⽗进程退出,init进程会为⼦进程“收⼫”。
⼀般⽽⾔,系统不希望⼤量进程长期处于僵⼫状态,因为会浪费系统资源。除了少量的内存资源外,⽐较重要的是进程ID。僵⼫进程并没有将⾃⼰的进程ID归还给系统,⽽是依然占有这个进程ID, 因此系统不能将该ID分配给其他进程。因此不建议使⽤⽅法⼆清除僵⼫进程。银婚金婚
如何防范/避免僵⼫进程的产⽣呢?
1、如果不关⼼⼦进程的退出状态,就应该将⽗进程对SIGCHLD的
处理函数设置为SIG_IGN,或者在调⽤sigaction函数时设置SA_
NOCLDWAIT标志位。
中学生好段摘抄2、如果⽗进程关⼼⼦进程的退出信息,则应该在流程上妥善设
计,能够及时地调⽤wait/waitpid,避免僵⼫状态。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论