在“后台”运行进程到底意味着什么?

在“后台”运行进程到底意味着什么?

我想更好地了解什么是后台进程。阅读这行代码后,问题就出现了:

/usr/sbin/rsyslogd -niNONE &

来源

文件说:

  -i pid file
         Specify an alternative pid file instead of the default
         one.  This option must be used if multiple instances of
         rsyslogd should run on a single machine. To disable
         writing a pid file, use the reserved name "NONE" (all
         upper case!), so "-iNONE".

  -n     Avoid auto-backgrounding.  This is needed especially if
         the rsyslogd is started and controlled by init(8).

来源

&符号&似乎意味着请求该命令在后台运行,请参见,例如这里

如果我的理解是正确的,pid文件与守护进程一起使用,即程序在后台运行时。

因此,从表面上看,所讨论的命令似乎首先告诉程序不要在后台运行-n,然后为 pid 文件指定 NONE ,以表明它不是守护进程1,然后紧接着指定&发送它进入背景。

我无法理解这一点。进程通常进入的背景是否是使用 发送到的不同背景&?从我读到的所有内容来看,后台的唯一含义似乎是 shell 未被阻止。在这方面,要求进程不要自动后台运行然后后台运行并没有多大意义。

我在这里缺少什么吗?具体的背景是什么? (当我们这样做时,谁负责删除 pid 文件?)


1 - 在出现问题的 docker 容器上下文中,当容器停止然后重新启动时,pid 文件的存在可能会导致问题。我不清楚是什么负责删除 pid 文件,一些消息来源表明它是init 系统,例如 systemd,而其他人暗示这是程序的责任。但是,如果使用 SIGKILL 杀死进程,则程序可能没有机会删除它,因此后续容器重新启动将失败,因为 pid 文件已经存在,但预计不会存在。

答案1

UNIX 后台进程的概念是作业控制的一部分。作业控制是围绕终端会话的进程组织。

守护进程通常不在终端会话中运行,因此它们不是 Unix 作业控制意义上的后台进程,只是在属于机器的“不可见”活动的一般计算意义上。这很可能是rsyslogd文档所指的内容:它指的是成为守护进程,而不是作业控制后台进程。

在交互式终端会话中,用户管理工作。每个工作是一组进程(可能是一个),由某些软件(通常是作业控制外壳)安排到该组中。会话中的每个作业都将终端作为其控制终端

后台/前台概念与这些作业之间终端设备的共享有关。在任何时候,进程组之一都会被指定为前台进程组。它可以从终端读取字符,并将输出发送到终端。其他进程组都是后台进程组。

作业控制 shell 结合来自 TTY 的信令和某些功能(例如tcsetpgrp.

前台进程组不仅可以从终端读取和写入,还可以接收 TTY 生成的信号,例如SIGINTfromCtrlCSIGTSTPfrom CtrlZ

通常,您使用CtrlZ将作业挂起到后台,然后使用作业控制命令让它bg在后台执行。

当您发出 时CtrlZ,前台进程组中的每个进程都会收到SIGTSTP信号并被挂起。作业控制 shell 检测到此更改,并进行库调用以将该作业移至后台,并使本身前台进程组。因此,shell 现在再次处于前台,它可以接收来自 TTY 的命令。

现在您可以输入背景,shell 将导致暂停的后台作业执行。

弗格命令将导致 shell 将自身从前台删除,并再次将后台作业放入前台。

后台作业不会接收来自 TTY 的字符驱动信号,例如SIGINT来自CtrlC.然而,当他们尝试读取或写入终端时,他们会收到类似的信号SIGTTOU,并被阻止执行该操作。

作业控制就像交通警察,守卫对终端的访问。

它类似于 GUI 中的窗口管理。在典型的 GUI 中,一个窗口具有“键盘焦点”。按键会转到该窗口。作业控制也是如此:可以说,前台进程组拥有“终端焦点”。

rsyslogd文档几乎可以肯定使用术语“背景”实际上意味着“变成守护进程”或“守护进程”。这与 POSIX 作业控制下的“后台作业”不同。

当服务器应用程序自动守护进程时,这意味着如果它在终端会话中运行,它将采取措施将自身从该会话中删除。它分叉一个孩子,然后分叉一个孙子。子进程终止,因此孙子成为孤儿,并且成为init守护进程的子进程。这是其中的一部分。另一部分是孙子将关闭标准输入、输出和错误文件描述符。因此它失去了与 TTY 的连接。可能会采取一些其他操作,例如更改到某些特定的工作目录。

rsyslogd如果由 运行,它不会自行守护进程,这是有道理的init,因为没有终端会话可以与之分离。 (但是,rsyslogd可以检测到它不是终端会话的一部分,并且在这种情况下不需要该-n标志。)

因此,实际上,服务器中 do-not-daemonize 命令行选项的主要用途是用于调试,具体原因如下:

  • 也许守护进程有一些调试跟踪模式,消息可以发送到标准输出。如果您想在控制台上观看这些消息,您不希望守护程序关闭其标准输出文件描述符。

  • 如果您想在调试器下调试守护进程,如果它只是退出,那么实际的守护进程活动发生在分叉的孙子中,这是不方便的。

  • 当您进行测试时,您可能希望对守护进程进行作业控制,例如使用 终止它CtrlC,或使用 挂起它CtrlZ

  • 有时,人们喜欢在终端多路复用软件(例如 GNU Screen 或 Termux)下运行服务器,其中服务器在终端会话中运行。自动守护进程会破坏其目的。

关于谁负责删除PID文件:主要是服务应用程序本身,如果它被干净地关闭的话。如果某个主进程正在管理服务,它可以知道其 PID 文件的路径,并在它们终止但未删除文件的情况下对其进行清理。 PID 文件通常放置在重新启动时会被擦除的目录中,例如/var/run,因此,如果系统发生灾难性故障并且必须重新启动,则重新启动会处理 PID 文件。

相关内容