Почему цикл событий asyncio подавляет KeyboardInterrupt в Windows?

У меня есть эта очень маленькая тестовая программа, которая ничего не делает кроме выполнения цикла событий asyncio:

import asyncio
asyncio.get_event_loop().run_forever()

Когда я запускаю эту программу в Linux и нажимаю Ctrl + C, программа будет корректно завершена с помощью исключения KeyboardInterrupt. В Windows нажатие Ctrl + C ничего не делает (протестировано с Python 3.4.2). Простой inifinite loop с time.sleep() корректно возвращает KeyboardInterrupt даже в Windows:

import time
while True:
    time.sleep(3600)

Почему цикл событий asyncio подавляет KeyboardInterrupt в Windows?

Ответ 2

Существует обходное решение для Windows. Запустите другую коррекцию, которая активирует цикл каждую секунду и разрешает цикл реагировать на прерывание клавиатуры.

Пример с Echo-сервером из 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
asyncio.async(wakeup())

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

Ответ 3

Если вы просто хотите выйти из программы и не нужно ловить 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()