Terminating a subprocess with KeyboardInterrupt
我正在使用Python使用subprocess模块??调用C ++程序。由于该程序需要花费一些时间才能运行,因此我希望能够使用Ctrl + C终止该程序。我在StackOverflow上看到了一些与此有关的问题,但是似乎没有一种解决方案适合我。
我想要的是子进程在KeyboardInterrupt上终止。这是我拥有的代码(类似于其他问题的建议):
1 2 3 4 5 6 7 8 9 10 11 12 13 | import subprocess binary_path = '/path/to/binary' args = 'arguments' # arbitrary call_str = '{} {}'.format(binary_path, args) proc = subprocess.Popen(call_str) try: proc.wait() except KeyboardInterrupt: proc.terminate() |
但是,如果运行此命令,则代码将挂起,等待进程结束,并且永远不会注册KeyboardInterrupt。我也尝试了以下方法:
1 2 3 4 5 6 7 8 9 10 11 | import subprocess import time binary_path = '/path/to/binary' args = 'arguments' # arbitrary call_str = '{} {}'.format(binary_path, args) proc = subprocess.Popen(call_str) time.sleep(5) proc.terminate() |
该代码段可以很好地终止程序,因此问题出在,不是发出终止信号的实际信号。
如何更改代码,以便可以在KeyboardInterrupt上终止子进程?
我正在运行Python 2.7和Windows 7 64位。提前致谢!
我尝试过的一些相关问题:
Python子进程Ctrl + C
KeyboardInterrupt后杀死subprocess.call
杀死python进程时杀死子进程?
我想出了一种方法,类似于让-弗朗索瓦(Jean-Francois)对循环的回答,但没有多个线程。 关键是使用Popen.poll()确定子进程是否已完成(如果仍在运行,则将返回None)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import subprocess import time binary_path = '/path/to/binary' args = 'arguments' # arbitrary call_str = '{} {}'.format(binary_path, args) proc = subprocess.Popen(call_str) try: while proc.poll() is None: time.sleep(0.1) except KeyboardInterrupt: proc.terminate() raise |
我在KeyboardInterrupt之后添加了一个额外的加薪,因此除了子进程之外,Python程序也被中断了。
编辑:根据eryksun的注释将pass更改为time.sleep(0.1),以减少CPU消耗。
我在Windows上的丑陋但成功的尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import subprocess import threading import time binary_path = 'notepad' args = 'foo.txt' # arbitrary proc = None done = False def s(): call_str = '{} {}'.format(binary_path, args) global done global proc proc = subprocess.Popen(call_str,stdout=subprocess.PIPE) proc.wait() done = True t = threading.Thread(target=s) t.start() try: while not done: time.sleep(0.1) except KeyboardInterrupt: print("terminated") proc.terminate() |
在运行子进程的地方创建一个线程。 导出
然后在非活动循环中永远等待。 当按CTRL + C时,将触发异常。 否则,进程间通信(例如:
注意:我已尝试使用