僵尸进程与孤儿进程

僵尸进程与孤儿进程

      在unix/Linux系统中,大多数情况下,子进程是通过父进程fork创建的。(注:系统调用fork,它调用一次,返回两个值,失败返回-1,成功时在子进程返回0,父进程返回所创建子进程的Pid)
      子进程创建后,子进程的结束和父进程的运行是一个异步过程。也就是说父进程没办法探测子进程什么时候结束。当一个子进程完成它的工作终止之后,其父进程需要调用wait()或waitpid()去获取子进程的终止状态。

孤儿进程
当一个进程的 父进程结束 时,但是它自己还没有结束,那么这个进程将会成为孤儿进程。最后孤儿进程将会被 init进程 (进程号为1)的进程收养,当然在子进程结束时也会由init进程完成对它的状态收集工作,因此一般来说,孤儿进程并不会有什么危害。
下面看一个关于孤儿进程的例子:

       在main函数中,创建子进程,然后让父进程休眠1S,让子进程先运行,打印出其进程id(pid)以及父进程id(ppid);随后子进程睡眠3S(此时会调度到父进程运行直至结束),目的是让父进程先于子进程结束,让子进程有个孤儿的状态;最后子进程再打印出其进程id(pid)以及父进程的id(ppid);观察两次打印的结果中其父进程id(ppid)的区别。



从运行结果来看,当其父进程结束后,子进程成为了孤儿进程,其 父进程id (ppid)为1,也就是说, init进程 成为该子进程的父进程了。

僵尸进程
一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的某些信息如进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
下面是一个关于僵尸进程的例子:在main函数中,创建子进程,然后让父进程睡眠10s,让子进程先终止(注意和孤儿进程例子的区别);这里子进程结束后父进程没有调用wait/waitpid函数获取其状态,用ps查看进程状态可以看出子进程为僵尸状态。



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

   僵尸进程的危害:
       僵尸进程会在系统中保留其某些信息,如进程描述符、进程id等等。以进程id为例,系统中可用的进程id是有限的,如果由于系统中大量的僵尸进程占用进程id,就会导致因为没有可用的进程id系统不能产生新的进程,这个问题就大了,这就是僵尸进程带来的危害。

猜你喜欢

转载自blog.csdn.net/ling_hun_pang_zi/article/details/80297633