gpt4 book ai didi

python - 在 KeyboardInterrupt 上杀死一系列子进程

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:05 26 4
gpt4 key购买 nike

我在编写启动本地 JBoss 实例的脚本时遇到了一个奇怪的问题。

我的代码看起来像这样:

with open("/var/run/jboss/jboss.pid", "wb") as f:
process = subprocess.Popen(["/opt/jboss/bin/standalone.sh", "-b=0.0.0.0"])
f.write(str(process.pid))

try:
process.wait()
except KeyboardInterrupt:
process.kill()

应该很容易理解,在运行时将 PID 写入文件,一旦我得到 KeyboardInterrupt,就终止子进程。

问题是在我发送 kill 信号后 JBoss 一直在后台运行,因为信号似乎没有传播到由 standalone.sh 启动的 Java 进程。

我喜欢使用 Python 编写系统管理脚本的想法,但是有很多像这样的奇怪边缘案例,如果我用 Bash 编写它,一切都会正常运行™。

当我得到一个 KeyboardInterrupt 时,如何杀死整个子进程树?

最佳答案

您可以使用 psutil 执行此操作图书馆:

import psutil

#..

proc = psutil.Process(process.pid)
for child in proc.children(recursive=True):
child.kill()

proc.kill()

据我所知,subprocess 模块不提供任何 API 函数来检索子进程生成的子进程,os 模块也不提供。


杀死进程的更好方法可能如下:

proc = psutil.Process(process.pid)
procs = proc.children(recursive=True)
procs.append(proc)

for proc in procs:
proc.terminate()

gone, alive = psutil.wait_procs(procs, timeout=1)
for p in alive:
p.kill()

这将使进程有机会正确终止,并且当超时结束时,其余进程将被终止。


请注意,psutil 还提供了一个 Popen 类,它具有与 subprocess.Popen 相同的接口(interface) plus all psutil.Process 的额外功能。您可能只想使用它而不是 subprocess.Popen。它也更安全,因为 psutil 会检查 PID 在进程终止时不会被重用,而 subprocess 不会。

关于python - 在 KeyboardInterrupt 上杀死一系列子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24894986/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com