为什么asyncio的事件循环会抑制Windows上的KeyboardInterrupt?

时间:2014-12-15 09:32:42

标签: python windows python-3.4 python-asyncio keyboardinterrupt

我有一个非常小的测试程序,除了执行asyncio事件循环之外什么都不做:

import asyncio
asyncio.get_event_loop().run_forever()

当我在Linux上运行此程序并按 Ctrl + C 时,程序将以KeyboardInterrupt异常正确终止。在Windows上按 Ctrl + C 不执行任何操作(使用Python 3.4.2测试)。即使在Windows上,使用time.sleep()的简单无限循环也会正确引发KeyboardInterrupt

import time
while True:
    time.sleep(3600)

为什么asyncio的事件循环会抑制Windows上的KeyboardInterrupt?

3 个答案:

答案 0 :(得分:15)

这是一个错误,当然。

有关解决问题进度的信息,请参阅issue on python bug-tracker

答案 1 :(得分:12)

Windows有解决方法。运行另一个corouting,它每秒唤醒循环并允许循环对键盘中断作出反应

来自asyncio doc的回声服务器示例

async def wakeup():
    while True:
        await asyncio.sleep(1)

loop = asyncio.get_event_loop()
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)

# add wakeup HACK
loop.create_task(wakeup())

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

答案 2 :(得分:8)

如果您只想退出该计划而不需要抓住KeyboardInterruptsignal模块会提供更简单(更有效)的解决方法:

# This restores the default Ctrl+C signal handler, which just kills the process
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

# Now the event loop is interruptable
import asyncio
asyncio.get_event_loop().run_forever()