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

skr*_*use 26 python windows keyboardinterrupt python-3.4 python-asyncio

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

import asyncio
asyncio.get_event_loop().run_forever()
Run Code Online (Sandbox Code Playgroud)

当我在Linux上运行此程序并按Ctrl+时C,程序将正常终止,但有KeyboardInterrupt异常.在Windows上按Ctrl+ C什么也没做(用Python 3.4.2测试).即使在Windows上,一个简单的无限循环也能正确time.sleep()引发KeyboardInterrupt:

import time
while True:
    time.sleep(3600)
Run Code Online (Sandbox Code Playgroud)

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

And*_*lov 19

肯定是这个错误.

请参阅python bug-tracker上的问题以解决问题.

  • Windows上的Ctrl-C将在Python 3.8中工作https://docs.python.org/dev/whatsnew/3.8.html#asyncio (4认同)

far*_*ncz 14

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
Run Code Online (Sandbox Code Playgroud)


Bar*_*son 11

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

# 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()
Run Code Online (Sandbox Code Playgroud)