[英]Terminate subprocess running in thread on program exit
基于这个问题的公认答案: python-subprocess-callback-when-cmd-exits我在一个单独的线程中运行一个子进程,并在子进程完成后执行一个可调用的。 一切都很好,但问题是,即使将线程作为守护进程运行,即使在程序正常退出或被kill -9
、 Ctrl + C 等杀死后,子进程仍继续运行......
下面是一个非常简化的示例(在 2.7 上运行):
import threading
import subprocess
import time
import sys
def on_exit(pid):
print 'Process with pid %s ended' % pid
def popen_with_callback(cmd):
def run_in_thread(command):
proc = subprocess.Popen(
command,
shell=False
)
proc.wait()
on_exit(proc.pid)
return
thread = threading.Thread(target=run_in_thread, args=([cmd]))
thread.daemon = True
thread.start()
return thread
if __name__ == '__main__':
popen_with_callback(
[
"bash",
"-c",
"for ((i=0;i<%s;i=i+1)); do echo $i; sleep 1; done" % sys.argv[1]
])
time.sleep(5)
print 'program ended'
如果主线程持续时间比子进程长,一切都很好:
(venv)~/Desktop|➤➤ python testing_threads.py 3
> 0
> 1
> 2
> Process with pid 26303 ended
> program ended
如果主线程持续时间少于子进程,则子进程继续运行直到它最终挂起:
(venv)~/Desktop|➤➤ python testing_threads.py 8
> 0
> 1
> 2
> 3
> 4
> program ended
(venv)~/Desktop|➤➤ 5
> 6
> 7
# hanging from now on
如果主程序完成或被杀死,如何终止子进程? 我尝试在 proc.wait 之前使用 atexit.register(os.kill(proc.pid, proc.wait
atexit.register(os.kill(proc.pid, signal.SIGTERM))
但它实际上是在运行子进程的线程退出时执行的,而不是在主线程退出时执行的。
我也在考虑轮询父 pid,但由于proc.wait
情况,我不确定如何实现它。
理想的结果是:
(venv)~/Desktop|➤➤ python testing_threads.py 8
> 0
> 1
> 2
> 3
> 4
> program ended
> Process with pid 1234 ended
使用Thread.join
方法,该方法将阻塞主线程,直到该线程退出:
if __name__ == '__main__':
popen_with_callback(
[
"bash",
"-c",
"for ((i=0;i<%s;i=i+1)); do echo $i; sleep 1; done" % sys.argv[1]
]).join()
print 'program ended'
我只是得到了一个丑陋但有效的方法。
只需设置一个全局变量来处理 proc=subprocess.Popen(),
你可以随时杀死 proc:
my_proc = None
def popen_with_callback(cmd):
def run_in_thread(command):
global my_proc
proc = subprocess.Popen(command, shell=False)
my_proc = proc
proc.wait()
on_exit(proc.pid)
return
...
然后你可以在程序中任何你想要的地方杀死proc。 做就是了:
my_proc.kill()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.