Почему я не могу поймать SIGINT, когда выполняется цикл событий asyncio?

используя Python 3.4.1 в Windows, я обнаружил, что при выполнении цикл событий asyncio моя программа не может быть прервана (т. е. при нажатии Ctrl+C в терминале). Более того, сигнал SIGINT игнорируется. И наоборот, я определил, что SIGINT обрабатывается, когда не в цикле событий.

почему SIGINT игнорируется при выполнении цикла событий asyncio?

приведенная ниже программа должна продемонстрировать проблему-запустите ее в терминале и попробуйте остановить его, нажав Ctrl+C, он должен продолжать работать:

import asyncio
import signal


# Never gets called after entering event loop
def handler(*args):
    print('Signaled')


signal.signal(signal.SIGINT, handler)

print('Event loop starting')
loop = asyncio.SelectorEventLoop()
asyncio.set_event_loop(loop)
loop.run_forever()
print('Event loop ended')

посмотреть обсуждение в официальном списке рассылки (Tulip).

3 ответов


Я нашел обходной путь, который заключается в планировании периодического обратного вызова. Во время этого запуска SIGINT, по-видимому, обрабатывается:

import asyncio


def wakeup():
    # Call again
    loop.call_later(0.1, wakeup)


print('Event loop starting')
loop = asyncio.SelectorEventLoop()
# Register periodic callback
loop.call_later(0.1, wakeup)
asyncio.set_event_loop(loop)
loop.run_forever()
print('Event loop ended')

Не уверен, почему это необходимо, но это указывает на то, что сигналы блокируются, пока цикл событий ждет событий ("опросы").

вопрос обсуждали в официальном списке рассылки (Tulip) мое обходное решение, по-видимому, является способом пойти на данный момент.

обновление

исправление предположительно пробился в Python 3.5, поэтому, надеюсь, мой обходной путь будет устаревшим этой версией Python.


Я обнаружил, что при выполнении цикла событий asyncio моя программа не может быть прервана (т. е. нажатием Ctrl+C в терминале)

чтобы уточнить: ctrl-C может не работать, но ctrl-break работает просто отлично.


обычно вы добавляете обратный вызов для них с loop.add_signal_handler() но, видимо, к сожалению, эта функция не поддерживается со встроенными циклами событий Windows:/

периодическая проверка может быть использована, да. В противном случае цикл выполняется вне signal способность модуля ловить сигналы.