我正在努力处理我从 Popen 开始的一些进程,这些进程启动了子进程。当我在终端中手动启动这些进程时,如果我发送 CTRL+C,每个进程都会按预期终止。但是使用 subprocess.Popen 在 python 程序中运行任何终止进程的尝试只会摆脱父进程而不是其子进程。
我尝试了 .terminate() ..kill() 以及 ..send_signal() 与 signal.SIGBREAK、signal.SIGTERM,但在每种情况下我都只是终止父进程。
通过这个父进程,我可以重现错误行为:
#!/usr/bin/python
import time
import sys
import os
import subprocess
import signal
if __name__ == "__main__":
print os.getpid(), "MAIN: start a process.."
p = subprocess.Popen([sys.executable, 'process_to_shutdown.py'])
print os.getpid(), "MAIN: started process", p.pid
time.sleep(2)
print os.getpid(), "MAIN: kill the process"
# these just terminate the parent:
#p.terminate()
#p.kill()
#os.kill(p.pid, signal.SIGINT)
#os.kill(p.pid, signal.SIGTERM)
os.kill(p.pid, signal.SIGABRT)
p.wait()
print os.getpid(), "MAIN: job done - ciao"
现实生活中的子进程是来自 Django 的 manage.py,它产生一些子进程并等待 CRTL-C。但下面的例子似乎也有效:
#!/usr/bin/python
import time
import sys
import os
import subprocess
if __name__ == "__main__":
timeout = int(sys.argv[1]) if len(sys.argv) >= 2 else 0
if timeout == 0:
p = subprocess.Popen([sys.executable, '-u', __file__, '13'])
print os.getpid(), "just waiting..."
p.wait()
else:
for i in range(timeout):
time.sleep(1)
print os.getpid(), i, "alive!"
sys.stdout.flush()
print os.getpid(), "ciao"
所以我的问题很简单:我如何杀死第一个示例中的进程并摆脱子进程?在 Windows 上 os.kill(p.pid, signal.CTRL_C_EVENT) 在某些情况下似乎可以工作,但是正确的方法是什么?终端是如何做到的?