进程后代

进程后代

我正在尝试构建一个进程容器。容器会触发其他程序。例如 - 使用“&”启动正在运行的后台任务的 bash 脚本。

我追求的重要功能是:当我杀死容器时,它下面产生的所有东西都应该被杀死。不仅是直系子女,还有他们的后代。

当我开始这个项目时,我错误地认为当你杀死一个进程时,它的子进程也会被自动杀死。我向有同样错误想法的人寻求建议。虽然捕捉到信号并将杀戮传递给孩子是可能的,但这不是我在这里寻找的。

我相信我想要实现的目标是可以实现的,因为当您关闭 xterm 时,其中运行的任何内容都会被杀死,除非它被 nohup 了。这包括孤立进程。这就是我想要重新创建的。

我有一个想法,我正在寻找的内容涉及 unix 会话。

如果有一种可靠的方法来识别进程的所有后代,那么能够向它们发送任意信号也会很有用。例如 SIGUSR1。

答案1

如果您向进程发送信号,该进程就会被终止。我想知道杀死一个进程也会杀死其他进程的谣言是如何开始的,这似乎特别违反直觉。

然而,有一些方法可以终止多个进程。但您不会向一个进程发送信号。你可以杀死整个进程组通过发送信号到-1234,其中1234是PGID(进程组ID),它是进程组领导者的PID。当你运行一个管道,整个管道作为一个进程组开始(应用程序可以通过调用来改变这一点)setpgid或者setpgrp)。

当您在后台 ( foo &) 启动进程时,它们位于自己的进程组中。进程组用于管理对终端的访问;通常只有前台进程组可以访问终端。后台作业保持不变会议,但是没有工具可以终止整个会话,甚至没有枚举会话中的进程组或进程的工具,因此这没有多大帮助。

当您关闭终端时,内核会发送信号SIGHUP到所有以其为自己的进程控制终端。这些过程形成一个会话,但并非所有会话都有控制终端。因此,对于您的项目,一种可能性是在自己的终端中启动所有进程,这些进程由脚本,屏幕等。终止终端仿真器进程以终止包含的进程(假设它们尚未与setsid)。

您可以通过以进程自己的用户身份运行进程来提供更多隔离,该用户不执行任何其他操作。然后很容易杀死所有进程:运行kill系统调用或者公用事业)作为该用户并使用 -1 作为杀死的 PID 参数,意思是“该用户的所有进程”。

您可以提供更多的隔离,但通过在实际的环境中运行包含的进程来进行更多的设置容器

答案2

识别进程的所有后代的可靠方法是使用命令,pstree <pid>其中 pid 是您的父进程 ID。

阅读手册页pstree 这里

向进程组的所有成员发出信号:killpg(<pgrp>, <sig>);
其中 pgrp 是进程组号,sig 是信号。

等待指定进程组中的子进程:waitpid(-<pgrp>, &status, ...);

您正在做的事情的替代方法是在新的 bash shell 中运行进程容器。使用该命令创建新的 bash shell bash,然后运行您的进程。当您希望结束所有进程时,请使用命令退出 shell exit

答案3

在父脚本中捕获终止信号并让它杀死所有子进程。例如,

#!/bin/bash
# kill the parent and children together
trap "kill 0" EXIT
# create all the children
for n in $(seq 1 100)
do
    ( echo "begin $n"; sleep 60; echo "end $n" ) &
done
# wait for the children to complete
wait

答案4

使用

unshare -fp --kill-child -- yourprogram

如果您 Kill unshare,所有子进程(yourprogram可能已生成)都将被终止。

现在可以通过 util-linux 实现这一点2.32我在上游实现了这个。它需要用户命名空间(内核配置选项CONFIG_USER_NS=y)或 root 权限。也可以看看这里

相关内容