31

我有这个非常小的测试程序,除了执行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?

4

3 回答 3

21

有适用于 Windows 的解决方法。运行另一个 corouting 每秒唤醒循环并允许循环对键盘中断做出反应

来自 asyncio doc 的 Echo 服务器示例

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
于 2016-04-28T21:25:30.710 回答
20

这是一个错误,当然。

有关解决问题的进度,请参阅python bug-tracker上的问题。

于 2014-12-15T20:13:48.613 回答
14

如果您只想退出程序而不需要捕获KeyboardInterrupt,则signal模块提供了一种更简单(更高效)的解决方法:

# 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()
于 2016-05-24T17:30:40.860 回答