僵尸进程&孤儿进程

僵尸进程
僵尸状态是一个比较特殊的状态,当进程退出并且父进程没有读取到子进程退出的相关信息就会产生僵尸进程。(可以理解为孩子死了还有遗言没有说给父亲听,导致有一口气一直咽下去,就变僵尸了)
僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码。即只要子进程退出,父进程还在进行,但父进程没有读取子进程状态,子进程就会一直保持在 僵尸状态(Z状态)。
接下来用代码来体现一下这个过程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
	pid_t pid = fork();
	if( 0 == pid)//child
	{
		int count = 10;
		while(count--)
		{
			printf("child...\n");
			sleep(3);
		}
	}
	else
	{
		while(1)
		{
			printf("father---\n");
			sleep(2);
		}
	}
	return 0;
}
这个程序很简单,就是让子进程循环打印一句话,父进程死循环打印一句话,将以上源程序编辑完成,运行程序就是父子进程向屏幕分别打印一句话,打开另一个终端,使用命令 ps -ef | grep a.out | grep -v grep查看当前的进程表,等到30秒后子进程退出或者自己使用命令把子进程杀死,再次使用命令ps -ef | grep a.out | grep -v grep,发现子进程依然存在,但是变成僵尸了。
       当再把父进程也杀死的时候,父进程会对自己的子进程进行扫描,如果某个子进程已经变成一个僵尸进程,那么,在被杀死之前会先将僵尸子进程留下的资源回收掉。但是,父进程不会变成僵尸。


处于僵尸态的进程的PCB依然存在,也就是说,其资源还没有完全被回收,还需要父进程来读取它的状态信息。
为什么将其杀死之后不直接将其资源完全回收呢?
孩子死了,父亲得知道孩子是怎么死的吧,所以,子进程在被杀死的时候会留下一些信息(留点临终遗言不过分吧)给父进程看。如果被杀死之后就将所有的资源释放掉了的话,系统就不知道曾经有哪个进程出现过。

为什么父进程不会变成僵尸呢?
因为使用fork创建出来的进程中的父进程2810的父进程是终端(终端是系统中的,能力比我们自己写的函数强大,所以系统终端创建出来的子进程都没有变成僵尸的机会)

kill是将一个进程杀死,但是不能将僵尸状态的进程杀死,因为处于僵尸状态的进程已经是死了。
kill后接进程号,是将该进程杀死
killall a.out    当killall 后边加上进程名,表示将该进程名下所有的进程都杀死

孤儿进程
当使用fork创建出了两个进程(一个父进程,一个子进程),当杀死父进程,而不杀死子进程,此时,子进程就变成了一个孤儿,系统就会将其托管到1号进程,(1号进程也是属于系统的)。
使用kill杀死孤儿进程时,孤儿进程不会变成僵尸。

将如上源程序编辑完成后执行,然后先将父进程杀死,发现,父进程没有变僵尸,再将子进程杀死,子进程也没有变成僵尸。




当再把父进程也杀死的时候,父进程会对自己的子进程进行扫描,如果某个子进程已经变成一个僵尸进程,那么,在被杀死之前会先将僵尸子进程留下的资源回收掉。但是,父进程不会变成僵尸。

猜你喜欢

转载自blog.csdn.net/guaiguaihenguai/article/details/79685453