守护进程为什么要分叉?

问题描述 投票:0回答:4

我知道一些(全部?)守护进程在启动时会分叉。我的印象是,这是以权限较低的用户身份运行子进程,特别是当守护进程类似于 HTTP 服务器时。

为什么这是必要的?进程不能在不分叉子进程的情况下启动并放弃其权限吗?分叉是“强制”的,还是有其他特殊原因(除了运行多个子工作进程之外)?

我是新手,非常感谢我能得到的所有帮助。

daemon fork
4个回答
20
投票

我认为守护进程分叉有几个原因:

  1. 一个原因是将进程与启动它的任何外壳分离。 有些 shell(例如 Bash)会在退出时杀死儿童,除非采取特殊的、特定于 shell 的预防措施。 分叉是避免这种情况的通用方法。

  2. 另一个原因是报告守护进程已成功启动

    假设它没有分叉。 您如何知道守护进程已成功启动? 您不能只读取和解析守护程序输出,因为守护程序管理程序应该以通用方式执行此操作。 所以唯一的方法就是获取程序的返回码。

    确实,如果守护进程无法启动(例如,找不到配置文件),您会立即知道。但是,嘿,如果一个守护进程已成功启动,它可能永远不会返回! 因此,您的守护进程管理器无法知道守护进程是否仍在尝试启动,或者已经启动并且正在工作。 分叉可以解决问题,如果分叉运行良好,分叉程序将返回成功。

  3. 至于特权,在execve

    之后删除它们比在
    execve
    之前删除它们要安全得多。  这是叉子方便的另一个原因。


9
投票
守护进程必须 fork 两次,因为它们必须独立于其他进程,也就是说,没有办法杀死守护进程来杀死另一个进程,并且必须在后台运行,不附加到终端。

启动时,守护进程分叉并且父进程死亡。这使得分叉进程成为

init

 的子进程,因此基本上它独立于其他进程。

在第二个分支上,子进程不再是进程领导者,并且与终端分离。

其他好的实践也可能适用,阅读简单守护进程的源代码可能会很有洞察力。


3
投票
我的印象是这样做是为了使守护进程完全不附加到任何其他进程(如 shell 或类似进程)。通过分叉并退出父进程,孤立进程将被系统 init 进程“采用”。


3
投票
为了支持 daramarak 所说的话,来自

维基百科的文章

在 Unix 环境中,父级 守护进程的进程通常是(但不是 总是)init 进程(PID=1)。 进程通常通过以下方式成为守护进程 分叉一个子进程,然后 有他们的父进程 立即退出,从而导致 init 采用子进程。这是一个 稍微简化的视图 与其他操作一样的过程 一般执行,例如 分离守护进程 任何控制 tty。方便 daemon(3) 等例程存在于 一些 UNIX 系统用于此目的。

基本上,该进程需要与其他进程和终端等解除关联。

© www.soinside.com 2019 - 2024. All rights reserved.