我正在处理一些使用Popen启动子进程的进程。当我在终端手动启动这些进程时,如果我发送CTRL+C,则每个进程都会按预期终止。但是,在使用subprocess.Popen运行python程序时,任何尝试终止进程的尝试都只会摆脱父进程而不是其子进程。
我尝试过 .terminate() ..kill() 以及..send_signal() 和 signal.SIGBREAK, signal.SIGTERM,但无论哪种情况下,我只能终止父进程。
我可以通过这个父进程重现该问题:
我尝试过 .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) 在某些情况下可以工作,但正确的方法是什么?终端又是如何做到的?