![默认情况下,内核是否会向成为孤立进程并包含已停止进程的进程组发送 SIGHUP 来终止所有进程?](https://linux22.com/image/145054/%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E5%86%85%E6%A0%B8%E6%98%AF%E5%90%A6%E4%BC%9A%E5%90%91%E6%88%90%E4%B8%BA%E5%AD%A4%E7%AB%8B%E8%BF%9B%E7%A8%8B%E5%B9%B6%E5%8C%85%E5%90%AB%E5%B7%B2%E5%81%9C%E6%AD%A2%E8%BF%9B%E7%A8%8B%E7%9A%84%E8%BF%9B%E7%A8%8B%E7%BB%84%E5%8F%91%E9%80%81%20SIGHUP%20%E6%9D%A5%E7%BB%88%E6%AD%A2%E6%89%80%E6%9C%89%E8%BF%9B%E7%A8%8B%EF%BC%9F.png)
在Linux编程接口中
要了解为什么孤立进程组很重要,我们需要从 shell 作业控制的角度来看待事物。根据图 34-3 考虑以下场景:
在父进程退出之前,子进程被停止(可能是因为父进程向其发送了停止信号)。
当父进程退出时,shell 将从其作业列表中删除父进程的进程组。子进程被 init 收养并成为终端的后台进程。包含子进程的进程组是孤立的。
此时,没有进程通过 wait() 监视已停止子进程的状态。
由于 shell 没有创建子进程,因此它不知道子进程的存在,也不知道子进程与已故父进程属于同一进程组。此外,init 进程仅检查终止的子进程,然后获取生成的僵尸进程。因此,停止的子进程可能会永远陷入困境,因为没有其他进程知道向其发送 SIGCONT 信号以使其恢复执行。
即使孤立进程组中已停止的进程在不同的会话中具有仍处于活动状态的父进程,也不能保证该父进程能够向已停止的子进程发送 SIGCONT。进程可以向同一会话中的任何其他进程发送 SIGCONT,但如果子进程位于不同的会话中,则适用发送信号的正常规则(第 20.5 节),因此父进程可能无法向子进程发送信号如果子进程是已更改其凭据的特权进程。
为了防止出现上述情况,SUSv3 指定:如果进程组成为孤儿并且有任何已停止的成员, 然后该组的所有成员都会收到一个 SIGHUP 信号,通知他们已与会话断开连接,然后发送一个 SIGCONT 信号,以确保他们恢复执行。如果孤立进程组没有任何已停止的成员,则不会发送信号。
SIGHUP 的默认操作是终止。那么,内核隐式向成为孤立进程并包含已停止进程的进程组发送 SIGHUP 是否意味着
组中的那些进程如果没有自己的 SIGHUP 配置,会被终止吗?组中任何停止的进程是否会首先由 SIGCONT 恢复并由 SIGHUP 终止?
为了使组中的进程生存,它们需要有自己的SIGHUP配置还是忽略SIGHUP?
谢谢。
答案1
请让我将 mosvy 的评论转化为答案:
是的是的。你可以看我回答里的注释这里实现该功能的 linux 源代码的链接(来自 linux 源代码的注释和实际代码比那篇散文或我对它的掩饰要好得多)