为什么 parent 在创建守护进程的过程中应该死掉

Why the parent should die, in the process of creating a Daemon

" 因此,启动守护进程的常用方法包括分叉一次或两次,并在 child 进程开始时使 parent 进程死亡执行其正常功能。" 我正在经历 OS 个概念,但我不理解上面所说的几行。 为什么在创建Daemon的过程中,会导致parent进程退出(或parent dying)? 有人可以解释一下吗。

这不是必需的,因为任何后台进程都可以是守护进程。从技术上讲,一个守护进程运行以运行一些一般的非交互式任务。在Unix环境下,守护进程一般被设置为一个进程,具有一些特点:没有控制终端,没有umask,特定的工作目录等。分叉两次是获得init进程继承的孙进程的常用方法,并且有前者属性,以某种方式使进程完全脱离任何用户控件(当然 root 除外)。

这仅适用于标准用户想要创建守护进程的情况。其他一些标准守护进程几乎正常创建(参见 init、launchd 等)

如果父进程退出而守护进程继续运行 运行,则守护进程是孤立的,并且 init 进程通常会采用它(即成为父进程)。

有一些例外,但通常预期守护进程将从 init 进程派生(例如 init 进程将在系统启动期间启动守护进程)。所以,如果另一个进程启动守护进程并终止,它就达到了预期的效果。

请注意,还需要一些其他操作,例如解除守护程序与任何 tty 的关联 window。

传统上,守护进程被定义为parent是系统的init进程,运行处于后台的进程。例如,如果您要在终端中执行某个程序,您的 shell 将创建一个进程(在前台或后台)并且该程序将 运行 以您的 shell 作为它的parent。这是一个 non-daemon 进程的示例,因为它的 parent 是您的 shell 进程。

那么如何产生一个parent是init进程的进程呢?好吧,一个 parent 进程在它 (child) 退出之前就死掉的进程变成了孤儿进程。一个孤儿进程将依次 re-parented 到 init 进程。瞧,进程现在符合守护进程的定义。

将此与您的引用联系起来,如果您分叉一次然后杀死 parent,您将达到预期的效果。同样,如果您 fork 一次然后 child fork 另一个进程,然后杀死第一个 child,您也可以在保持(现在 grandparent)进程存活的同时达到预期的效果.

其他答案已经解释了当 parent 终止时会发生什么,即 child 被 init 进程采用。

但是为什么需要上面的内容来创建进程守护进程?根据定义,守护进程是 non-interacting 程序,即它不应与终端相关联。这确保即使用户通过 Control-C、挂断等方式发送信号,守护进程也能继续在后台工作。现在,如何防止进程连接到终端?通过杀死原始 parent 使其成为 parent。 init 是一个特殊的进程,因为:

  • 它没有连接到任何终端。
  • 它是引导 OS 后的第一个进程 (pid 1),这使它成为会话的领导者。请注意,每个 UNIX 进程都属于一个进程组,而该进程组又属于一个会话。会话中的第一个进程成为会话负责人。

在 UNIX 中,只有会话领导者可以附加到(或控制)终端。一旦你对你的进程进行 init parent,它就会加入 init 的会话。由于 init 是会话领导者,您的进程永远不会成为领导者,因此永远不会附加到终端。这就是我们想要的,对吧?

还有其他方法可以分离终端,例如调用 setsid 但这不是本次讨论的一部分。