![为什么守护进程没有关联的终端?](https://linux22.com/image/134185/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E6%B2%A1%E6%9C%89%E5%85%B3%E8%81%94%E7%9A%84%E7%BB%88%E7%AB%AF%EF%BC%9F.png)
我对创建 Linux 守护进程的惯例有点困惑。人们大多同意,守护进程的组成部分是没有关联的终端。此外,在示例代码中,进程的父进程通常会被终止,守护进程将重新设置父进程以初始化。我完全理解这是这样做的方法,但是为什么呢?该进程没有关联的终端并且是 init 的直接子进程,这有什么好处?
答案1
https://en.wikipedia.org/wiki/SIGHUP
1. 进程没有关联的终端有什么好处?
在 POSIX 兼容平台上,SIGHUP(“信号挂断”)是发送到进程的信号当其控制终端关闭时。 (它最初的设计目的是通知串行线路掉线的进程。)
[...]
POSIX 兼容系统上的默认操作 [SIGHUP] 是异常终止。
如果我对情况的理解正确的话,有两种不同的情况。
明显的情况是如果你关闭终端仿真器,例如 GNOME Terminal 或者mc
,关闭伪终端设备的主端。这个闭包会在伪终端上产生挂起。这会影响从设备。所有受该终端控制的进程都会收到SIGHUP。这是不是上述情况。
@JDePB指出第二种情况:如果关闭所有引用终端设备的文件描述符,也会产生挂断。也就是说,如果您的守护进程关闭其 tty 的 FD(它应该这样做),并且稍后在其他打开 tty 退出的 FD 的进程上,您的守护进程将收到 SIGHUP,即使您的终端仿真器没有响应并离开master端伪终端打开。可以通过以下方式对整个终端设备禁用此功能清算HUPCL。
还有vhangup()
。似乎login
调用此方法是为了尝试确保前一个会话不会干扰它。或者其他的东西。我不太清楚,因为这个调用是 Linux 特定的,并且手册页非常非常短。
2. 是 init 的直接子进程吗?
如果接收 SIGHUP 的进程是 Unix shell,那么作为作业控制的一部分,它通常会拦截该信号并确保所有停止的进程在之前继续运行向子进程发送信号(更准确地说,进程组,在 shell 内部表示为“作业”),默认情况下终止它们。