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

2019-07-03 14:30:52 +08:00
 v2byy

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

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

为什么非要 fork 两次呢?

3500 次点击
所在节点    Linux
5 条回复
iwong0exv2
2019-07-03 14:33:56 +08:00
因为大多数时候父进程不能退啊
v2byy
2019-07-03 14:35:05 +08:00
@iwong0exv2 如果是这样的话,那明白了,多谢。
raysonx
2019-07-03 14:57:52 +08:00
> 父进程 fork 一次,然后父进程直接退出,那子进程不是直接被 init 收养?

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

Fork 二次的目的是为了保证守护进程从当前的 controlling terminal 上 detach,并且不会重新获得 controlling terminal。
原因是,当你在子进程执行一次 setsid 的时候,这个进程会被分配一个新的 session,于是这个进程得以从当前的 controlling terminal 上脱离。但是这个进程作为新 session 的第一个进程,会成为 session lead,它可以重新获取一个 controlling terminal。为了杜绝这种可能,再 fork 一次后,孙进程就不是 session lead 了,它不能重新获取 controlling terminal。
neoblackcap
2019-07-03 15:10:26 +08:00
@raysonx 的说法是正确的,这个原理 APUE 有讲解。当然现在创建守护进程也有其他的方法,比如 daemon(),不过好像兼容性不是那么好,所以还是 fork 2 次为主。
Hardrain
2019-07-03 23:49:46 +08:00
deamonize 时候记得 fork()两次后还要 setsid()吧
得让被 init"收养"的 orphaned process 有自己的 session。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/579650

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX