在正在等待事件的程序中捕获键盘中断

Nav*_*vin 5 python windows multithreading windows-7 python-3.x

以下程序挂起终端,使其忽略Ctrl+C.这是相当烦人的,因为每次其中一个线程挂起时我必须重新启动终端.

有没有什么方法可以KeyboardInterrupt等待一个事件?

import threading
def main():
    finished_event = threading.Event()
    startThread(finished_event)
    finished_event.wait()#I want to stop the program here
    print('done!')
def startThread(evt):
    """Start a thread that will trigger evt when it is done"""
    #evt.set()
if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

小智 5

如果你想避免轮询,你可以使用信号模块的pause()功能来代替。是一个阻塞函数,当进程接收到一个信号时就会解除阻塞。在这种情况下,当按下 ^C 时,SIGINT 信号会解除该功能的阻塞。请注意,根据文档,该功能在 Windows 上不起作用。我已经在 Linux 上试过了,它对我有用。finished_event.wait()signal.pause()

我在这个 SO thread 中遇到了这个解决方案。

  • 我想你可以编辑你的答案更简单直接,但你解决了我的问题,谢谢! (2认同)

jfs*_*jfs 4

更新:当前Python 3finished_event.wait()可以在我的Ubuntu机器上运行(从Python 3.2开始)。您不需要指定timeout参数,即可使用 来中断它Ctrl+C。您需要timeout在 CPython 2 上传递参数。

这是一个完整的代码示例:

#!/usr/bin/env python3
import threading

def f(event):
    while True:
        pass
    # never reached, otherwise event.set() would be here

event = threading.Event()
threading.Thread(target=f, args=[event], daemon=True).start()
try:
    print('Press Ctrl+C to exit')
    event.wait()
except KeyboardInterrupt:
    print('got Ctrl+C')
Run Code Online (Sandbox Code Playgroud)

可能存在与Ctrl+C相关的错误。测试它是否适用于您的环境。


旧的民意调查答案:

您可以尝试让解释器运行主线程:

while not finished_event.wait(.1): # timeout in seconds
    pass
Run Code Online (Sandbox Code Playgroud)

如果您只想等待子线程完成:

while thread.is_alive():
    thread.join(.1)
Run Code Online (Sandbox Code Playgroud)