为什么在守护进程时 fork() 两次?
Why fork() twice while daemonizing?
我想知道为什么人们两次调用 fork()
以及为什么第一次调用是在 setsid()
.
之前执行的
是的,如果调用者已经是进程组组长,则不会创建新会话。但是,如果我不让 (grand)parent 成为流程组组长怎么办?谁会为我做(不问我)? (好吧,也许是 1llum1n4t1、Sc13nt0l0gy、美国国家安全局……;))
是的,第一个 child 应该 立即退出 不要创建僵尸进程。但是 (grand)parent 不能在分叉后退出吗?或者,一两次 fprintf(stderr,...
或 write(2,...
调用(如 "successfully started daemon xy")是否会如此 大事 ? (我不能用另一种方式来防止僵尸吗?)
总而言之,这个双fork()
-"magic"真的需要(不惹事)吗?
还是只是传统或 so-called "best practise"(比如避免 goto
)?
或者它只是保证守护进程在 "historical"(当然我的意思是 "far too old for usage in production environments")平台上工作,比如 SVr4、BSD 3、RHEL 2 或一些蹩脚的 32 位嵌入式平台?
第一次调用 fork(2)
确保该进程不是组长,这样该进程就有可能创建一个新会话并成为会话组长。第一个 fork(2)
还有其他原因:如果守护进程是作为 shell 命令启动的,进程分叉和父进程退出会使 shell 返回到它的提示符并等待更多命令。
第二个 fork(2)
是为了确保新进程不是会话领导者,所以它不会(意外地)分配控制终端,因为守护进程不应该有一个控制终端。关于第二个分支,这里引用了 UNIX 环境中的高级编程,第 13 章(守护进程):
Under System V-based systems, some people recommend calling fork again
at this point, terminating the parent, and continuing the daemon in
the child. This guarantees that the daemon is not a session leader,
which prevents it from acquiring a controlling terminal under the
System V rules. Alternatively, to avoid acquiring a controlling
terminal, be sure to specify O_NOCTTY whenever opening a terminal
device.
那本书的第 13.3 节描述了在守护进程时使用的更多规则和模式,如果可以的话,花时间阅读它是非常值得的。
我想知道为什么人们两次调用 fork()
以及为什么第一次调用是在 setsid()
.
是的,如果调用者已经是进程组组长,则不会创建新会话。但是,如果我不让 (grand)parent 成为流程组组长怎么办?谁会为我做(不问我)? (好吧,也许是 1llum1n4t1、Sc13nt0l0gy、美国国家安全局……;))
是的,第一个 child 应该 立即退出 不要创建僵尸进程。但是 (grand)parent 不能在分叉后退出吗?或者,一两次 fprintf(stderr,...
或 write(2,...
调用(如 "successfully started daemon xy")是否会如此 大事 ? (我不能用另一种方式来防止僵尸吗?)
总而言之,这个双fork()
-"magic"真的需要(不惹事)吗?
还是只是传统或 so-called "best practise"(比如避免 goto
)?
或者它只是保证守护进程在 "historical"(当然我的意思是 "far too old for usage in production environments")平台上工作,比如 SVr4、BSD 3、RHEL 2 或一些蹩脚的 32 位嵌入式平台?
第一次调用 fork(2)
确保该进程不是组长,这样该进程就有可能创建一个新会话并成为会话组长。第一个 fork(2)
还有其他原因:如果守护进程是作为 shell 命令启动的,进程分叉和父进程退出会使 shell 返回到它的提示符并等待更多命令。
第二个 fork(2)
是为了确保新进程不是会话领导者,所以它不会(意外地)分配控制终端,因为守护进程不应该有一个控制终端。关于第二个分支,这里引用了 UNIX 环境中的高级编程,第 13 章(守护进程):
Under System V-based systems, some people recommend calling fork again at this point, terminating the parent, and continuing the daemon in the child. This guarantees that the daemon is not a session leader, which prevents it from acquiring a controlling terminal under the System V rules. Alternatively, to avoid acquiring a controlling terminal, be sure to specify O_NOCTTY whenever opening a terminal device.
那本书的第 13.3 节描述了在守护进程时使用的更多规则和模式,如果可以的话,花时间阅读它是非常值得的。