我正在使用以下命令启动子流程:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
但是,当我尝试杀死使用:
p.terminate()
或者
p.kill()
该命令一直在后台运行,所以我想知道如何才能真正终止该过程。
请注意,当我使用以下命令运行命令时:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
发出时,它确实成功终止p.terminate()
。
使用进程组,以便能够向组中的所有进程发送信号。为此,你应该将会话ID附加到生成的子进程的父进程中,在你的情况下,这是一个外壳程序。这将使其成为流程的小组负责人。因此,现在,当信号发送到流程组负责人时,它将被传输到该组的所有子流程。
这是代码:
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
如何
subprocess.CREATE_NEW_PROCESS_GROUP
涉及到这个?我们的测试建议setid!= setpgid,而os.pgkill只杀死仍然具有相同进程组ID的子进程。更改了进程组的进程不会被杀死,即使它们可能仍具有相同的会话ID ...
@PiotrDobrogost:
CREATE_NEW_PROCESS_GROUP
可用于start_new_session=True
在Windows上进行仿真我不建议您使用os.setsid(),因为它还有其他作用。其中,它断开了控制TTY的连接,并使新流程成为流程组负责人。参见win.tue.nl/~aeb/linux/lk/lk-10.html
您将如何在Windows中执行此操作?
setsid
仅在* nix系统上可用。