Почему я не могу поймать 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
способность модуля ловить сигналы.