Автор оригинала: Doug Hellmann.
Уведомления о мероприятиях системы Unix обычно прерывают приложение, вызывая свой обработчик. При использовании с ASYNCIO
обратные вызовы обработчиков сигналов чередуются с другими COROUTINES и обратными обратными вызовами, управляемыми контуром события. Это приводит к меньшему количеству прерванных функций, и в результате необходимость обеспечить безопасную охранников для очистки неполных операций.
Обработчики сигналов должны быть регулярными каплями, а не COROUTINES.
asyncio_signal.py
import asyncio import functools import os import signal def signal_handler(name): print('signal_handler({!r})'.format(name))
Обработчики сигналов зарегистрированы с использованием ADD_SIGNAL_HANDLER ()
. Первый аргумент – это сигнал, а второй – обратный вызов. Обратные обратные вызовы не передаются аргументам, поэтому, если аргументы нужны функция, функция может быть завернута <код> funcctools.partial () .
event_loop asyncio.get_event_loop() event_loop.add_signal_handler( signal.SIGHUP, functools.partial(signal_handler, name'SIGHUP'), ) event_loop.add_signal_handler( signal.SIGUSR1, functools.partial(signal_handler, name'SIGUSR1'), ) event_loop.add_signal_handler( signal.SIGINT, functools.partial(signal_handler, name'SIGINT'), )
Этот пример программы использует COROUTINE для отправки сигналов для себя через OS.KILL ()
. После того, как каждый сигнал отправляется, COROUTINE дает контроль, чтобы позволить обработчику работать. В нормальном применении было бы больше мест, где код приложения дает обратно на петлю событий, и не требуется, чтобы искусственный доход не понадобится.
async def send_signals(): pid os.getpid() print('starting send_signals for {}'.format(pid)) for name in ['SIGHUP', 'SIGHUP', 'SIGUSR1', 'SIGINT']: print('sending {}'.format(name)) os.kill(pid, getattr(signal, name)) # Yield control to allow the signal handler to run, # since the signal does not interrupt the program # flow otherwise. print('yielding control') await asyncio.sleep(0.01) return
Основная программа работает <код> send_signals () до тех пор, пока не отправит все сигналы.
try: event_loop.run_until_complete(send_signals()) finally: event_loop.close()
Выходной вывод показывает, как обработчики вызываются при SEND_Signals ()
дают контроль после отправки сигнала.
$ python3 asyncio_signal.py starting send_signals for 21772 sending SIGHUP yielding control signal_handler('SIGHUP') sending SIGHUP yielding control signal_handler('SIGHUP') sending SIGUSR1 yielding control signal_handler('SIGUSR1') sending SIGINT yielding control signal_handler('SIGINT')
Смотрите также
- Сигнал – получение уведомления асинхронных системных событий