zoukankan      html  css  js  c++  java
  • 说说僵尸和孤儿进程的那点儿事

    1.什么是孤儿进程,僵尸进程?

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

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

    知乎上一个朋友的解释很有趣:

    孤儿进程:没有父进程的进程就是孤儿进程,孤儿进程会被init领养,成为一个准守护进程。

    僵尸进程:如果进程他爹活着,但是不给子进程收尸(wait、waitpid),子进程就会变成僵尸。

    2.孤儿进程和僵尸进程有什么危害?

    僵尸进程:

      unix提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题。如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,一些进程的状态信息会一直都在系统里面,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

    Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集(如供父进程),除此之外,僵尸进程不再占有任何内存空间。实际上,任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。  如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

    孤儿进程:

      孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

    下面这段比喻形容了进程的一生,也更容易看出僵尸进程所处的阶段:

    随着一句fork,一个新进程呱呱落地,但它这时只是老进程的一个克隆。

    然后随着exec,新进程脱胎换骨,离家独立,开始了为人民服务的职业生涯。

    人有生老病死,进程也一样,它可以是自然死亡,即运行到main函数的最后一个"}",从容地离我们而去;也可以是自杀,自杀有2种方式,一种是调用exit函数,一种是在main函数内使用return,无论哪一种方式,它都可以留下遗书,放在返回值里保留下;它还甚至能可被谋杀,被其它进程通过另外一些方式结束他的生命。

    进程死掉以后,会留下一具僵尸,wait和waitpid充当了殓尸工,把僵尸推去火化,使其最终归于无形。

    这就是进程完整的一生。

    3.如何避免孤儿和僵尸的产生?

     为避免产生僵尸进程,实际应用中一般采取的方式是:

    1.将父进程中对SIGCHLD信号的处理函数设为SIG_IGN(忽略信号);

    2.fork两次并杀死一级子进程,令二级子进程成为孤儿进程而被init所“收养”、清理。 

    参考资料:

      https://www.cnblogs.com/Anker/p/3271773.html

           http://blog.csdn.net/Erica_1230/article/details/71106765

  • 相关阅读:
    CentOS7 安装Docker 18.09.5
    CentOS7 安装Jenkins 2.164.2
    Python3从零开始爬取今日头条的新闻【一、开发环境搭建】
    Win10 安装Oracle11g2、配置PL/SQL Developer11环境
    IDEA 使用Mybatis效率飞起来的必备工具:MybatisCodeHelperPro 最新破解版,亲测可用!
    Navicat Premium 12 (64位)实现连接Oracle 11 (64位)
    VMware14 安装CentOS7 实现宿主机ping通虚拟机、虚拟机ping通宿主机、虚拟机能上网且能ping通百度
    Java中util.Date通过mybatis向数据库中datetime的操作!
    Java中try-catch-finally语句中return的执行顺序总结
    java中this用法总结
  • 原文地址:https://www.cnblogs.com/curo0119/p/8006005.html
Copyright © 2011-2022 走看看