将程序作为守护程序运行并使用'&'将其派生到后台之间有什么区别?


Answers:


31

守护进程的传统方式是:

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

这样可以确保该进程不再与终端在同一个进程组中,因此不会被杀死。IO重定向是为了使输出不出现在终端上。


5
因此,如果关闭了产生后台进程(&)的终端,后台进程也会终止吗?
user1561108 2012年

9
当终端退出时,该过程将收到SIGHUP,该信号的默认处理程序是终止该过程。
丹尼斯·考斯玛克

12
请在&您的答案中添加零件说明。它似乎不完整..如果您检查原始问题。
mtk 2012年

1
这是因为使用&在后台运行事物并不会使过程做任何特别的事情:)
Dennis Kaarsemaker,2012年

33

对于守护程序,您想要的是一个与任何事物都没有关系的进程。至少,您希望它位于自己的会话中,不附加到终端,不希望从父对象继承的任何文件描述符对任何对象都开放,不希望父对象(除init之外)拥有当前对象目录中/以免造成不必要的负担...

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

由于该过程是会话的领导者,因此如果打开终端设备,就有可能成为该终端的控制过程。第二次分叉确保它不会发生。

另一方面,&在交互式外壳程序中派生并创建一个新的进程组(以使其不在终端的前台进程组中),而在非交互式外壳程序中,派生一个进程并忽略其中的SIGINT。它不会与终端分离,也不会关闭文件描述符(尽管某些shell会将stdin重新打开为/dev/null)...


chdir(“ /”)有什么用?关闭文件描述符?
Timothy Leung

@TimothyLeung,请参见编辑。
斯特凡Chazelas

8

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

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


1
另外,要回答上述分离过程而不是将其保留为终端的子过程的技术方面,您可以尝试运行“ nohup firefox&”
Odaym 2012年

7

随着command &当父母去世你的过程将得到一个SIGHUP信号被杀死。

不过,系统管理员可以访问某些解决方法。

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

(trap '' HUP; command) &

这将打开一个子外壳,HUP用一个空的处理程序捕获信号并用“与”号分叉。

输出可能仍会重定向到错误的位置tty。否则迷路。
您可以修复与&>command.out1>output.out2>errors.out

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

nohup command &

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


2
只是要注意,使用ZSH,您可以将command &以后的版本与Shell 分离disown,然后再将其用作no -hup。
数学
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.