[英]Terminating a subprocess with KeyboardInterrupt
I'm using Python to call a C++ program using the subprocess module. 我正在使用Python使用subprocess模块调用C ++程序。 Since the program takes some time to run, I'd like to be able to terminate it using Ctrl+C. 由于该程序需要花费一些时间才能运行,因此我希望能够使用Ctrl + C终止该程序。 I've seen a few questions regarding this on StackOverflow but none of the solutions seem to work for me. 我在StackOverflow上看到了一些与此有关的问题,但是似乎没有一种解决方案适合我。
What I would like is for the subprocess to be terminated on KeyboardInterrupt. 我想要的是子进程在KeyboardInterrupt上终止。 This is the code that I have (similar to suggestions in other questions): 这是我拥有的代码(类似于其他问题的建议):
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()
However, if I run this, the code is hung up waiting for the process to end and never registers the KeyboardInterrupt. 但是,如果运行此命令,则代码将挂起,等待进程结束,并且永远不会注册KeyboardInterrupt。 I have tried the following as well: 我也尝试了以下方法:
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()
This code snippet works fine at terminating the program, so it's not the actual signal that's being sent to terminate that is the problem. 该代码段可以很好地终止程序,因此问题出在,不是发出终止信号的实际信号。
How can I change the code so that the subprocess can be terminated on KeyboardInterrupt? 如何更改代码,以便可以在KeyboardInterrupt上终止子进程?
I'm running Python 2.7 and Windows 7 64-bit. 我正在运行Python 2.7和Windows 7 64位。 Thanks in advance! 提前致谢!
Some related questions that I tried: 我尝试过的一些相关问题:
Python sub process Ctrl+C Python子进程Ctrl + C
Kill subprocess.call after KeyboardInterrupt KeyboardInterrupt后杀死subprocess.call
kill subprocess when python process is killed? 杀死python进程时杀死子进程?
I figured out a way to do this, similar to Jean-Francois's answer with the loop but without the multiple threads. 我想出了一种方法,类似于让-弗朗索瓦(Jean-Francois)对循环的回答,但没有多个线程。 The key is to use Popen.poll() to determine if the subprocess has finished (will return None if still running). 关键是使用Popen.poll()确定子进程是否已完成(如果仍在运行,则将返回None)。
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
I added an additional raise after KeyboardInterrupt so the Python program is also interrupted in addition to the subprocess. 我在KeyboardInterrupt之后添加了一个额外的加薪,因此除了子进程之外,Python程序也被中断了。
EDIT: Changed pass to time.sleep(0.1) as per eryksun's comment to reduce CPU consumption. 编辑:根据eryksun的注释将pass更改为time.sleep(0.1),以减少CPU消耗。
My ugly but successfull attempt on Windows: 我在Windows上的丑陋但成功的尝试:
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()
Create a thread where the subprocess runs. 在运行子进程的地方创建一个线程。 Export the proc
variable. 导出proc
变量。
Then wait forever in a non-active loop. 然后在非活动循环中永远等待。 When CTRL+C is pressed, the exception is triggered. 当按CTRL + C时,将触发异常。 Inter-process communication (ex: proc.wait()
) is conflicting with CTRL+C handling otherwise. 进程间通信(例如: proc.wait()
)与CTRL + C处理发生冲突。 When running in a thread, no such issue. 在线程中运行时,没有这样的问题。
note: I have tried to avoid this time loop using threading.lock()
but stumbled on the same CTRL+C ignore. 注意:我已经尝试使用threading.lock()
来避免这个时间循环,但是偶然发现了相同的CTRL + C忽略。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.