僵尸进程 孤儿进程

当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()取得子进程的终止状态。如果进程不调用wait/waitpid的话,那么系统保留的那段子进程信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

孤儿进程是没有父进程的进程,孤儿进程这个重任就落在了init进程身上,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,因此孤儿进程并不会有什么危害。

Linux允许进程查询内核以获得父进程的PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如wait()/waitpid()这样的库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。

为了遵循这些设计原则,不允许Linux内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被终止的进程相关的wait()类系统调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上说进程已死,但必须保存它的描述符,直到父进程调用得到通知。

如果一个进程已经终止,但是它的父进程尚未调用wait()或waitpid()对它进行处理,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。

僵尸进程是如何产生的

在UNIX系统中,一个进程结束了,但是它的父进程没有等待(调用wait/waitpid)它,那么它将变成一个僵尸进程。通过ps命令查看其带有defunct的标志。僵尸进程是一个早已结束的进程,但在进程表(process table)中仍占了一个位置(slot)。

但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就有init进程接管它,称为它的父进程,从而保证每个进程都会有一个父进程。而init进程会自动wait其子进程,因此被init接管的所有进程都不会变成僵尸进程。

只有wait了子进程,并最终释放他们占用的系统进程表中的资源和进程号,这样,这些僵死的孤儿进程就彻底被清除了。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符(PCB)仍然保存在系统中。这种进程称之为僵尸进程。

任何一个子进程(init除外)在exit之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时处理,可能用ps就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

孤儿进程是没有父进程的进程,孤儿进程这个重任就落在了init进程身上,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,因此孤儿进程并不会有什么危害。

原文地址:https://www.cnblogs.com/caohongchang/p/11618826.html

时间: 2024-12-01 17:21:18

僵尸进程 孤儿进程的相关文章

系统编程之进程的创建.僵尸与孤儿进程

一.进程 进程是正在执行的程序实例.执行程序时,内核会将程序代码载入虚拟内存,为程序变量分配空间,在内核中建立相应的数据结构,以记录与进程有关的各种信息(比如,进程ID.用户ID.组ID以及终止状态等) 在内核看来,进程是一个个实体,内核必须在它们之间共享各种计算机资源.对于像内存这样的受限资源来说,内核一开始会为进程分配一定数量的资源,并 在进程的生命周期内,统筹该进程和整个系统对资源的需求,对这一分配进行调整.程序终止时,内核会释放所有此类资源,供其他进程重新使用.其他资源(如 CPU.网络

Linux 僵尸进程 孤儿进程

今天有人问到了僵尸进程 和孤儿进程,以前遇到过,但是没有太注意,这里mark 一下 僵尸进程 :进程 fork 出来子进程,但是 父进程没有调用wait 或waitpid 获取子进程的状态信息,子进程的进程描述符任然保存在系统中 查找僵尸进程 ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' 孤儿进程 :父进程退出,子进程任然在继续,孤儿进程将被init( 1) 收养,并由Init完成对他们的信息采集 僵尸进程的危害:进程退出时候,内核将释放所有资源,包括打

浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.

其实有时想想linux内核的设计也蕴含着很多人生哲学,在linux中有这么几个特殊进程中,我们一开始见到它们的名字可能还会觉得很诧异,但在了解完了原理后,我们仔细想想,这样的命名也不无道理!下面我就给大家分别介绍一下这三种特殊的进程! 1.孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这是子进程的父进程就是init进程(1号进程).其实还是很好理解的. #include <sys/types.h> #include <unistd.h> #inclu

戏说守护、僵尸、孤儿进程

首先说简单的结论: 没有父进程的进程就是孤儿进程,孤儿进程会被init领养,成为一个准守护进程. 如果进程他爹活着,但是不给子进程收尸(wait.waitpid),子进程就会变成僵尸. 守护进程(Daemon)是在一类脱离终端在后台执行的程序, 通常以 d 结尾, 随系统启动, 其父进程 (ppid) 通常是 init 进程 以下是Wikipedia中关于Daemon的定义: In multitasking computer operating systems, a daemon (/dimn/

进程——wait与waitpid、僵尸进程与孤儿进程

僵尸进程:子进程终止了,但是父进程没有回收子进程的资源PCB.使其成为僵尸进程 孤儿进程:父进程先与子进程结束了,使得子进程失去了父进程,这个时候子进程会被1号进程init进程领养,成为孤儿进程 为了防止上面两种情况,我们应当在父进程结束之前一定要回收子进程的所有资源 所以出现了wait和waitpid #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status); pid_t waitpid(pid_t

(转)进程间关系:进程、僵尸进程、孤儿进程、进程组、前台进程组、后台进程组、孤儿进程组、会话、控制终端

不同的shell对使用管道线时创建子进程的顺序不同,本文以bash为例,它是支持作业控制的shell的典型代表. 僵尸进程与孤儿进程 僵尸进程:先于父进程终止,但是父进程没有对其进行善后处理(获取终止子进程有关信息,释放它仍占有的资源).消灭僵尸进程的唯一方法是终止其父进程.孤儿进程:该进程的父进程先于自身终止.其特点是PPID=1(init进程的ID).一个孤儿进程可以自成孤儿进程组. 文中用到的缩写 PID = 进程ID (由内核根据延迟重用算法生成)PPID = 父进程ID(只能由内核修改

fork()函数的执行过程、孤儿进程和僵尸进程

说起fork就不得不提COW(Copy On Write),就是"写时拷贝".也就是当fork发生时,子进程根本不会去拷贝父进程的内存页面,而是与父进程共享.当子进程或父进程需要修改一个内存页面时,Linux就将这个内存页面复制一份给修改者,然后再去修改,这样从用户的角度看,父子进程根本就没有共享什么内存.COW也就是进程要写共享的内存页面,先复制再改写. 采用了COW技术后,fork时,子进程还需要拷贝父进程的页面表.这种拷贝的代价就非常小了,对于CPU来说用不了几个时钟周期. 1.

Linux下的僵尸进程和孤儿进程

说明 在UNIX里,除了进程0(即PID=0的交换进程,Swapper Process)以外的所有进程都是由其他进程使用系统调用fork创建的,这里调用fork创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程. 操作系统内核以进程标识符(Process Identifier,即PID)来识别进程.进程0是系统引导时创建的一个特殊进程,在其调用fork创建出一个子进程(即PID=1的进程1,又称init)后,进程

Linux - 进程 (二) 进程创建

详细见:https://github.com/ZhangzheBJUT/linux 一 进程概述 一个进程都由另一个称之为父进程的进程启动,被父进程启动的进程叫做子进程.Linux系统启动时候,它将运行一个名为init的进程,该进程是系统运行的第一个进程,它的进程号为1,它负责管理其它进程,可以把它看做是操作系统进程管理器,它是其它所有进程的祖先进程.系统中的进程要么是由init进程启动,要么是由init进程启动的其他进程启动. 使用ps命令输出中的PPID栏给出的是父进程的进程ID,它是启动这