【Linux进程】僵尸进程与孤儿进程

前言

        僵尸进程和孤儿进程是Linux中极为重要的两个种进程状态, 本文将会围绕这三个问题: 是什么? 为什么? 如何产生的? 详细的介绍这两种进程; 以及一些使用场景.

在这里插入图片描述

 僵尸进程

 在了解孤儿进程之前, 需要先引入僵尸进程的概念;

 什么是僵尸进程?

僵尸进程: 就是处于僵死状态的进程;

        僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程, 没有读取到子进程退出的返回代码时就会产生僵死()进程
为什么会产生僵尸进程?

         进程 = 进程PCB + 进程的代码和数据; 进程存在就一定会占用一定的空间;

        为什么创建进程? 很简单, 为了让它帮我们完成某些任务;

        进程执行完毕之后, 核心任务: 将进程PCB 以及进程的代码和数据释放掉;

        父进程创建子进程, 让子进程去完成某些任务, 那么父进程可能有需求: 需要知道子进程的任务完成情况;

        子进程退出时, 会由OS将子进程的退出信息写入到进程PCB中, 允许进程的代码和数据被释放, 但是进程PCB不会立即释放, 要让父进程知道 子进程退出的信息, 得知子进程退出的原因(正常退出或者异常退出);

         当一个进程退出了, 代码和数据已经被释放, 只要PCB中的退出信息还没有被 OS或父进程读取到, OS就必须维护这-退出进程的PCB, 此时的进程状态就是Z状态, 也就是僵尸状态;

         只有被父进程读取后(wait)后, PCB的状态才会将Z状态改为X状态, 然后被OS回收;

危害 :

        一个进程处于Z状态, 父进程一直不读取回收, 那么该进程的PCB就会一直存在, 造成内核级的内存泄露(内核资源浪费);

         这种危害主要在一些服务器中较为明显, 服务器的服务会长时间的运行, 长时间的积累就会导致服务的效率变慢, 虽然重启服务器可以将僵尸进程的PCB资源释放, 但是对于服务器而言, 不可能轻易的关闭后重启;

 模拟僵尸进程的产生:

int main()
{
	 pid_t id = fork();
	if (id < 0) return 1;
	else if (id == 0) //子进程执行5秒后退出
	{
		int cnt = 5;
		while (cnt)
		{
			printf("I am child , runing time:%d\n", cnt--);
			sleep(1);
		}
		printf("I am child ,dead!:%d\n", cnt--);
		
		exit(2);
	}
	else // 父进程一直运行, 但不回收子进程
	{
		while (1)
		{
			printf("I am father, running times!\n");
			sleep(1);
		}
	}
	return 0;
}

 使用指令监控进程的状态变化:

while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done // myprocess为需要监控的进程名

 孤儿进程

 什么是孤儿进程?

        父进程先退出,子进程就称之为“孤儿进程”

父进程先退出,? 那么子进程退出时不就没有进程来读取子进程的PCB退出信息了吗? 

        孤儿进程被1号init进程(OS)领养
 为什么被1号进程领养?

        为了避免子进程退出, 没有进程读取子进程PCB的情况发生; 

        父进程一旦退出, 子进程如果还没有执行完毕, 就会被OS领养, 当子进程执行完毕退出后, 由OS进行读取回收; 

模拟孤儿进程的产生:

int main()
{
	pid_t id = fork();
	if (id < 0) return 1;
	else if (id == 0) // 子进程一直运行
	{
		while (1)
		{
			printf("I am child ...\n");
			sleep(1);
		}
	}
	else // 父进程运行5秒后退出
	{
		int cnt = 5;
		while (cnt)
		{
			printf("I am father, running time:%d\n", cnt--);
			sleep(1);
		}
		printf("I am father dead:%d\n", cnt--);
		exit(2);
		
	}
	return 0;
}

 监控指令:

while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done // myprocess为需要监控的进程名

 孤儿进程在实际应用中的使用:

        孤儿进程的特性在一些并发服务中可以使用,  服务器服务接收请求, 对请求进行处理时可以让任务处理的主进程创建子进程去执行, 而主进程立即退出, 此时子进程就会变成孤儿进程, 被OS领养, 当子进程执行完毕后, 由OS进行回收, 任务处理的进程也不需要一直的等待子进程处理完毕;

 


总结

        孤儿进程是为了避免父进程退出, 造成子进程无法被读取, 导致子进程变成僵尸进程的情况; 僵尸进程对于服务器服务来说危害极大, 在编写服务时要特别注意; 好了以上便是本文的全部内容, 希望对你有所帮助,  感谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值