使用 KeyboardInterrupt 终止子进程
Terminating a subprocess with KeyboardInterrupt
我正在使用 Python 调用使用子进程模块的 C++ 程序。由于该程序需要一些时间才能 运行,我希望能够使用 Ctrl+C 终止它。我在 Whosebug 上看到了一些关于此的问题,但 none 的解决方案似乎对我有用。
我想要的是在 KeyboardInterrupt 上终止子进程。这是我的代码(类似于其他问题中的建议):
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。我也尝试了以下方法:
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 sub process Ctrl+C
Kill subprocess.call after KeyboardInterrupt
kill subprocess when python process is killed?
我在 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()
创建子进程运行的线程。导出 proc
变量。
然后在非活动循环中永远等待。当按下 CTRL+C 时,将触发异常。进程间通信(例如:proc.wait()
)与 CTRL+C 处理冲突。当运行在线程中时,没有这样的问题。
注意:我曾尝试使用 threading.lock()
来避免此时间循环,但无意中遇到了相同的 CTRL+C 忽略。
我想出了一个方法来做到这一点,类似于 Jean-Francois 对循环的回答,但没有多线程。关键是使用 Popen.poll() 来确定子进程是否已完成(如果仍然 运行,将 return 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
我在 KeyboardInterrupt 之后添加了一个额外的 raise,所以 Python 除了子进程之外,程序也被中断了。
编辑:根据 eryksun 的评论将传递更改为 time.sleep(0.1) 以减少 CPU 消耗。
我正在使用 Python 调用使用子进程模块的 C++ 程序。由于该程序需要一些时间才能 运行,我希望能够使用 Ctrl+C 终止它。我在 Whosebug 上看到了一些关于此的问题,但 none 的解决方案似乎对我有用。
我想要的是在 KeyboardInterrupt 上终止子进程。这是我的代码(类似于其他问题中的建议):
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。我也尝试了以下方法:
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 sub process Ctrl+C
Kill subprocess.call after KeyboardInterrupt
kill subprocess when python process is killed?
我在 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()
创建子进程运行的线程。导出 proc
变量。
然后在非活动循环中永远等待。当按下 CTRL+C 时,将触发异常。进程间通信(例如:proc.wait()
)与 CTRL+C 处理冲突。当运行在线程中时,没有这样的问题。
注意:我曾尝试使用 threading.lock()
来避免此时间循环,但无意中遇到了相同的 CTRL+C 忽略。
我想出了一个方法来做到这一点,类似于 Jean-Francois 对循环的回答,但没有多线程。关键是使用 Popen.poll() 来确定子进程是否已完成(如果仍然 运行,将 return 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
我在 KeyboardInterrupt 之后添加了一个额外的 raise,所以 Python 除了子进程之外,程序也被中断了。
编辑:根据 eryksun 的评论将传递更改为 time.sleep(0.1) 以减少 CPU 消耗。