进程后代

Cra*_*ner 25 process signals fork container

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

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

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

我相信我想要实现的目标,因为当你关闭一个 xterm 时,它里面运行的任何东西都会被杀死,除非它被 nohup'd。这包括孤立进程。这就是我想要重新创建的。

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

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

Gil*_*il' 31

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

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

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

当您关闭终端时,内核会将信号发送SIGHUP到所有将其作为控制终端的进程。这些进程形成一个会话,但并非所有会话都有一个控制终端。因此,对于您的项目,一种可能性是在它们自己的终端中启动所有进程,这些进程由scriptscreen等创建。终止终端模拟器进程以终止包含的进程(假设它们没有与 分离setsid)。

您可以通过以自己的用户身份运行进程来提供更多的隔离,他们不做任何其他事情。然后很容易终止所有进程:以该用户身份运行kill系统调用实用程序)并使用 -1 作为终止的 PID 参数,意思是“该用户的所有进程”。

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


小智 6

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

#!/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
Run Code Online (Sandbox Code Playgroud)


jar*_*rno 6

您可以使用这种 shell 脚本:

set -m; (
# start the processes in this container:
...
) & set +m; pid=$!
...
# terminate the container:
kill -- -"$pid"
Run Code Online (Sandbox Code Playgroud)

诀窍是为容器子 shell 启用作业控制,以便在那里执行的进程获得通用的唯一进程组 ID,您可以通过给定命令使用该 IDkill来终止所有进程。


Chr*_*ing 5

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

阅读pstree 此处的手册页。

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

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

您正在做的另一种选择是在新的 bash shell 中运行您的进程容器。使用该命令创建新的 bash shell,bash然后运行您的进程。当您希望结束所有进程时,请使用命令退出 shell exit


归档时间:

查看次数:

19346 次

最近记录:

4 年,11 月 前