今天讲述僵尸进程.
首先关于僵尸进程的介绍:僵尸进程就是某进程产生的子进程返回后,其父进程没有及时处理该进程的终止状态。
根据PIDH和PPID可以看出进程的父子关系,但是考虑到父进程先终止,那么其子进程会如何呢?当然会由INIT进程收养,此时,对应的PPID将会变成1。
关于里面的细节,操作过程如下:(摘自unix环境高级编程)
在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止进程的子进程,如果是,则将该进程的父进程ID更改为1(init进程的ID)。这种处理方式保证了每个进程都有一个父进程.
接着说关于僵尸进程,这涉及到一些函数,这里就介绍其中一种.
wait函数。wait(int * stat)
wait函数让父进程阻塞等待子进程的终结,子进程终结后会返回某个值,保存在内核中,信息大体上又进程ID,进程的终止状态,进程使用的CPU时间总量....,wait从内核中获取进程的终止状态值,然后讲数值传递到对应的STAT地址上。wait成功后返回改进程的PID.
wait就是从内核中取出数据,如果未取出数据,该子进程则会处于僵死状态.
为了验证上述所说,我这里就列举我的实验吧.
首先先验证一下关于进程的init进程的收养孤儿进程的实例吧.
如下代码:
#include"unistd.h"
#include"stdio.h"
int main()
{
pid_t pid;
int status;
int u=9;
if((pid=fork())==0){printf("this is child:%d\n",getpid());
while(1) sleep(1);}
printf("this is parent:%d\n",getpid());
return 0;
}
然后
./a.out
this is parent:7185
this is child:7186
ps -ef|grep 718
Huix 7186 1 0 21:51 pts/2 00:00:00 ./a.out
可以看出,对应的子进程的ppid变成了1,验证正确。
接着开始做僵尸进程的程序,先看代码:
#include"unistd.h"
#include"stdio.h"
int main()
{
pid_t pid;
int status;
int u=9;
if((pid=fork())==0){return 0;}
while(1) sleep(1);
return 0;
}
编译好后,ps -ef|grep a.out
ps aux|grep a.out
观察结果如下:
Huix 7201 6263 0 21:56 pts/2 00:00:00 ./a.outt
Huix 7202 7201 0 21:56 pts/2 00:00:00 [a.out]
Huix 7218 7203 0 21:56 pts/3 00:00:00 grep a.out
Huix 7201 0.0 0.0 3924 340 pts/2 S+ 21:56 0:00 ./a.out
Huix 7202 0.0 0.0 0 0 pts/2 Z+ 21:56 0:00 [a.out]
Huix 7220 0.0 0.0 103260 856 pts/3 S+ 21:56 0:00 grep a.out
看见z+了吗,这就是僵尸进程。
当然,如果子进程结束了,没有清理掉,而父进程也结束了,那么内核会自动帮助清理僵尸进程。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29454248/viewspace-1075161/
,如需转载,请注明出处,否则将追究法律责任。