Почему я не могу поймать 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).
Ответы
Ответ 1
Я нашел обходное решение, которое должно планировать периодический обратный вызов. Хотя это работает, 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), мой способ обхода, по-видимому, теперь идет.
Update
Исправление предположительно пробилось в Python 3.5, так что, надеюсь, мое обходное решение будет устаревшим из-за этой версии Python.
Ответ 2
Я обнаружил, что при выполнении цикла событий asyncio моя программа не может быть прервана (т.е. нажав Ctrl + C в терминале)
Чтобы уточнить: ctrl-C может не работать, но ctrl-break работает просто отлично.
Ответ 3
Обычно вы добавляете обратный вызов для них с loop.add_signal_handler()
, но, к сожалению, эта функция не поддерживается встроенными циклами событий Windows:/
Можно использовать периодическую проверку, да. В противном случае цикл работает за пределами возможности модуля signal
для захвата сигналов.