进程概念之孤儿与僵尸

      在了解了进程是什么后,接下来我们来了解一下进程的其他相关。

      进程可以使用命令来进行查看

  •   进程的信息可以通过/proc系统文件夹查看;(如要查看PID为1 的进程信息,需要查看/proc/1这个文件夹)
  • 大多数进程信息同样也可以用top和ps这些用户级工具来获取

     通过系统调用获取进程标识符的方法:

     进程ID(PID):调用函数getpid();

     父进程ID(PPID):调用函数getppid();

     在学习过进程的创建和销毁之后,我们应该会听过孤儿进程与僵尸进程这两个概念,接下来就来学习一下这两个进程的概念以及来由。  孤儿进程与僵尸产生的方式均为kill+进程名(或者进程ID),若杀死的为父进程,则产生孤儿进程;若杀死的为子进程,则产生的为僵尸进程。

     僵尸进程:僵尸进程就是死后无人收尸,所以演变成僵尸,也就是,父进程还活着,但子进程因为某些原因而被杀死,然鹅父进程没有得到子进程死亡的任何通知,所以该子进程就称为僵尸进程。

  • 僵尸状态是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵尸进程。
  • 僵尸进程会以种植状态保持在进程表中,并且会一直在等待父进程读取退出代码。
  • 所有,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。

      下面我们就来模拟一下僵尸进程的产生。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	pid_t id=fork();
	if(id<0)
	{
		perror("fork");
		return 1;
	}
	else if(id>0)
	{//parent
		printf("parent[%d] is sleeping...\n ",getpid());
		sleep(30);
	}
	else
	{
	    printf("child[%d] is begin Z....\n",getpid());
	    sleep(5);
	    exit(EXIT_SUCCESS);
	}
	return 0;
}

      测试结果:

         先运行缩写代码:


         再打开一个终端,创建一个监控命令行脚本进行监控就可以观察到进程的状态:


      僵尸进程的危害:

  • 进程的退出状态必须被维持下去,因为它要告诉关系它的进程(父进程),交给它的任务完成的怎么样了?可是如果父进程一直不读取,那子进程就一直处于Z状态。
  • 维持退出状态本身就是要用数据维护,也属于进程基本信息,所有保存在task_struct(PCB)中,也就是说,如果Z状态一直不退出,PCB就要一直进行维护。
  • 但是你也知道,一个父进程会创建许多子进程,如果不回收,就会造成内存资源的浪费。因为数据结构对象本身就是就要占用内存资源。

      孤儿进程:我们可以用字面意思来解释,孤儿的意思就是无父无母,而我们都知道,进程只有父进程,所有孤儿进程的意思就是父进程已被销毁,然鹅子进程依然存活,因此,我们把该子进程称为孤儿进程。但,如父进程死后,所有的孤儿进程将由1号进程(也就是操作系统所提供的1号进程来管理),当然,前提是子进程不为僵尸进程。

  • 父进程如果提前退出,那么子进程后退出,进入Z状态后,该如何处理呢?
  • 父进程先退出,那么子进程就称为“孤儿进程”。
  • 孤儿进程被1号init进程收养,当然也要有init进程进行回收喽。

    接下来进行孤儿进程的实现:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
	pid_t id=fork();
	if(id<0)
	{
		perror("fork");
		return 1;
	}
	else if(id==0)
	{//child
		printf("I'm child,pid:%d\n",getpid());
		sleep(10);
	}
	else
	{//parent
		printf("I'm parent,pid:%d\n",getpid());
		sleep(3);
		exit(0);
	}
	return 0;
}

     在监视命令行脚本的监视下,运行结果如下:


  以上就是我对孤儿进程与僵尸进程的简单总结。




猜你喜欢

转载自blog.csdn.net/weixin_38175489/article/details/79705868