如何终止使用 shell=True 启动的 python 子进程 [英] How to terminate a python subprocess launched with shell=True
问题描述
我正在使用以下命令启动一个子进程:
I'm launching a subprocess with the following command:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
但是,当我尝试使用以下方法杀死时:
However, when I try to kill using:
p.terminate()
或
p.kill()
该命令一直在后台运行,所以我想知道如何才能真正终止该进程.
The command keeps running in the background, so I was wondering how can I actually terminate the process.
请注意,当我使用以下命令运行命令时:
Note that when I run the command with:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
在发出 p.terminate()
时它确实成功终止.
It does terminate successfully when issuing the p.terminate()
.
推荐答案
使用 进程组以便能够向组中的所有进程发送信号.为此,您应该将 会话 ID 附加到衍生/子进程,在您的情况下是一个外壳.这将使它成为流程的组长.所以现在,当一个信号被发送到进程组组长时,它会被传输到这个组的所有子进程.
Use a process group so as to enable sending a signal to all the process in the groups. For that, you should attach a session id to the parent process of the spawned/child processes, which is a shell in your case. This will make it the group leader of the processes. So now, when a signal is sent to the process group leader, it's transmitted to all of the child processes of this group.
代码如下:
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # Send the signal to all the process groups
这篇关于如何终止使用 shell=True 启动的 python 子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!