将程序作为守护进程运行和使用“&”将其分叉到后台有什么区别?

将程序作为守护进程运行和使用“&”将其分叉到后台有什么区别?

从系统管理员的角度来看,在基于 UNIX 的系统上部署服务时有哪些实际差异?

答案1

对于守护进程,您想要的是一个与任何事物都没有联系的进程。至少,您希望它位于自己的会话中,不附加到终端,没有从父级继承的任何文件描述符打开任何东西,没有父级照顾您(除了 init 之外)拥有当前目录/以免阻止卸载...

要从终端分离,您需要创建一个新会话,但是,要创建会话,您不能是组(或会话)领导者,因此最好是分叉一个新进程。假设父进程退出,这也意味着该进程将不再有父进程,并将被 init 采用。然后,关闭所有可能的文件描述符,你chdir("/")(不能关闭当前工作目录来释放该资源,就像文件描述符一样,使/当前工作目录至少不会阻止卸载目录)。

因为该进程是会话领导者,所以存在这样的风险:如果它打开终端设备,它就会成为该终端的控制进程。第二次分叉可确保这种情况不会发生。

另一方面,&,在交互式 shell 中,分叉并创建一个新的进程组(以免位于终端的前台进程组中),在非交互式 shell 中,分叉进程并忽略其中的 SIGINT。它不会与终端分离,不会关闭文件描述符(尽管有些 shell 会重新打开标准输入/dev/null)...

答案2

传统的守护进程方式是:

fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()

这确保该进程不再与终端位于同一进程组中,因此不会与终端一起被杀死。 IO重定向是为了让输出不会出现在终端上。

答案3

作为守护进程运行程序/进程与使用 & 符号将其分叉到后台之间的区别基本上与所有权有关。

最常见的是,守护进程的父进程是在里面进程(Unix 系统上启动的第一个进程),守护进程是该进程的子进程,意味着它不受您作为非特权用户的直接控制。另一方面,将程序/进程分叉到后台意味着您可以随时将其调用回前台和/或终止它。

答案4

当父进程死亡时,您的进程command &将被 SIGHUP 信号杀死。

如果程序没有明确支持“守护程序模式”(即忽略 HUP 信号),系统管理员仍然可以访问一些解决方法。

在 bash 系统上,您可以使用:

(trap '' HUP; command) &

这将打开一个子 shell,HUP用空处理程序捕获信号并对其进行“&”号/分叉。

输出可能仍会被重定向到错误的tty。或者迷路。
您可以使用&>command.out1>output.out和修复该问题2>errors.out

在大多数系统上,您可能还可以访问该nohup命令。
nohup大大简化了这个过程。这是相当标准的,但我发现许多 busybox 嵌入式 ARM 发行版都缺少它。你只需写:

nohup command &

..你就完成了。输出被重定向到 IIRC nohup.out,但可以使用选项更改此文件名。

相关内容