【发布时间】:2017-01-22 19:43:19
【问题描述】:
我正在使用 Python 调用使用 subprocess 模块的 C++ 程序。由于程序需要一些时间来运行,我希望能够使用 Ctrl+C 来终止它。我在 StackOverflow 上看到了一些与此相关的问题,但似乎没有一个解决方案适合我。
我希望子进程在 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()
这段代码 sn-p 可以很好地终止程序,所以问题不是发送到终止的实际信号。
如何更改代码以在 KeyboardInterrupt 上终止子进程?
我正在运行 Python 2.7 和 Windows 7 64 位。提前致谢!
我尝试过的一些相关问题:
【问题讨论】:
-
为什么不在主程序中捕获 ctrl-c 信号并使用它来调用
proc.terminate()? -
在 Python 3 中,您可以使用
_winapi.WaitForMultipleObjects([proc._handle], False, -1)。对于主线程,如果 wait-all 标志为 false,此等待会自动包含 Python 的SIGINT事件。在 2.x 中,您必须使用 ctypes 或 PyWin32 从头开始实现。 -
@eryksun 感谢您的建议。有一个名为 win32event 的模块具有类似的功能,可以为 Python 2 导入,但我尝试了
win32event.WaitForMultipleObjects([proc._handle], False, -1)并没有什么不同。 -
@limi44, 3.x 使用由 Ctrl+C 的信号处理程序设置的 Windows 事件对象。调用
_winapi.WaitForMultipleObjects时,此事件会自动添加到列表中。在 2.x 中实现这一点需要 PyWin32 或 ctypes 定义一个控制台CTRL_C_EVENT处理程序(例如,将 ctypes 回调函数传递给SetConsoleCtrlHandler),它设置一个事件(通过CreateEvent创建)。然后包装WaitForMultipleObjects以将Ctrl+C 事件句柄附加到列表并在等待之前重置事件(ResetEvent),但仅在从主线程调用时。
标签: python windows subprocess interrupt terminate