V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
v2byy
V2EX  ›  Linux

unix 中解决僵尸进程 fork 两次的原因?

  •  
  •   v2byy · 2019-07-03 14:30:52 +08:00 · 3469 次点击
    这是一个创建于 1730 天前的主题,其中的信息可能已经有所发展或是发生改变。

    据我了解,fork 两次是为了避免产生僵尸进程。第一次 fork 产生的子进程 exit 之后,第二次 fork 的子进程被 init 进程收养,从而避免了使得 grandchild 称为僵尸进程。

    有一点不明,如果这样,那 fork 一次不就行了吗?父进程 fork 一次,然后父进程直接退出,那子进程不是直接被 init 收养?

    为什么非要 fork 两次呢?

    5 条回复    2019-07-03 23:49:46 +08:00
    iwong0exv2
        1
    iwong0exv2  
       2019-07-03 14:33:56 +08:00
    因为大多数时候父进程不能退啊
    v2byy
        2
    v2byy  
    OP
       2019-07-03 14:35:05 +08:00
    @iwong0exv2 如果是这样的话,那明白了,多谢。
    raysonx
        3
    raysonx  
       2019-07-03 14:57:52 +08:00   ❤️ 4
    > 父进程 fork 一次,然后父进程直接退出,那子进程不是直接被 init 收养?

    这句话是正确的,只要父进程退出,子进程的父进程就会变成 init。

    Fork 二次的目的是为了保证守护进程从当前的 controlling terminal 上 detach,并且不会重新获得 controlling terminal。
    原因是,当你在子进程执行一次 setsid 的时候,这个进程会被分配一个新的 session,于是这个进程得以从当前的 controlling terminal 上脱离。但是这个进程作为新 session 的第一个进程,会成为 session lead,它可以重新获取一个 controlling terminal。为了杜绝这种可能,再 fork 一次后,孙进程就不是 session lead 了,它不能重新获取 controlling terminal。
    neoblackcap
        4
    neoblackcap  
       2019-07-03 15:10:26 +08:00
    @raysonx 的说法是正确的,这个原理 APUE 有讲解。当然现在创建守护进程也有其他的方法,比如 daemon(),不过好像兼容性不是那么好,所以还是 fork 2 次为主。
    Hardrain
        5
    Hardrain  
       2019-07-03 23:49:46 +08:00 via Android
    deamonize 时候记得 fork()两次后还要 setsid()吧
    得让被 init"收养"的 orphaned process 有自己的 session。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3486 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 10:55 · PVG 18:55 · LAX 03:55 · JFK 06:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.