Подтвердить что ты не робот

Asyncio - Как можно использовать сопрограммы в обработчиках сигналов?

Я разрабатываю приложение, использующее asyncio из python3.4 для работы в сети. Когда это приложение отключается чисто, node необходимо "отключить" от концентратора. Это отключение является активным процессом, который требует сетевого подключения, поэтому цикл должен дождаться завершения этого процесса до закрытия.

Моя проблема заключается в том, что использование сопрограммы в качестве обработчика сигнала приведет к тому, что приложение не отключится. Пожалуйста, рассмотрите следующий пример:

import asyncio
import functools
import os
import signal

@asyncio.coroutine
def ask_exit(signame):
    print("got signal %s: exit" % signame)
    yield from asyncio.sleep(10.0)
    loop.stop()

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                                        functools.partial(ask_exit, signame))

print("Event loop running forever, press CTRL+c to interrupt.")
print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())
loop.run_forever()

Если вы запустите этот пример и нажмите Ctrl + C, ничего не произойдет. Вопрос в том, как мне сделать это поведение с siganls и сопрограммами?

4b9b3361

Ответ 1

Синтаксис для python >= 3.5

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                            lambda: asyncio.ensure_future(ask_exit(signame)))

Ответ 2

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                            asyncio.async, ask_exit(signame))

Таким образом, сигнал заставляет ваш ask_exit получать запланированное задание.