Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 杀死键盘中断上的一系列子进程_Python_Subprocess - Fatal编程技术网

Python 杀死键盘中断上的一系列子进程

Python 杀死键盘中断上的一系列子进程,python,subprocess,Python,Subprocess,我在编写脚本启动本地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 Keyboard

我在编写脚本启动本地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写入文件,一旦我得到
键盘中断
,杀死子进程

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

我喜欢使用Python编写系统管理脚本的想法,但是有很多像这样的奇怪的边缘情况,如果我用Bash编写,一切都会正常工作™.

当我获得
键盘中断时,如何杀死整个子进程树?

您可以使用库执行此操作:

据我所知,
子流程
模块不提供任何API函数来检索子流程生成的子流程,
操作系统
模块也不提供


终止进程的更好方法可能是:

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
相同的接口以及
psutil.Process
的所有额外功能。您可能只想使用它而不是
subprocess.Popen
。它也更安全,因为
psutil
检查进程终止时不会重用PID,而
subprocess
则不会

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()