【问题标题】:Why does the asyncio's event loop suppress the KeyboardInterrupt on Windows?为什么 asyncio 的事件循环会抑制 Windows 上的 KeyboardInterrupt?
【发布时间】:2014-12-15 09:32:42
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    来自异步文档的 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
    

    【讨论】:

      【解决方案2】:

      这是一个错误,当然。

      问题解决进度见issue on python bug-tracker

      【讨论】:

      【解决方案3】:

      如果您只想退出程序而不需要捕获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()
      

      【讨论】:

      • 此解决方案是否清理套接字连接?
      • @Jiu 这只是导致进程退出。操作系统将关闭任何打开的套接字。请参阅superuser.com/questions/375604 了解更多信息。
      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      相关资源
      最近更新 更多