Потоковые обработчики
Исходный код: Lib/asyncio/runners.py
В этом разделе описаны высокоуровневые примитивы asyncio для запуска кода asyncio.
Они построены на базе цикла событий с целью упростить использование асинхронного кода для распространённых сценариев.
Запуск программы asyncio
-
asyncio.run(coro, *, debug=None, loop_factory=None) -
Выполните корутину coro и верните результат.
Эта функция запускает переданную корутину, заботясь о управлении циклом событий asyncio, завершении асинхронных генераторов и закрытии исполнителя.
Эта функция не может быть вызвана, когда другой цикл событий asyncio работает в том же потоке.
Если debug равно
True, цикл событий будет запущен в отладочном режиме.Falseявным образом отключает отладочный режим.Noneиспользуется для соблюдения глобальных настроек Отладочного режима.Если loop_factory не
None, используется для создания нового цикла событий; в противном случае используетсяasyncio.new_event_loop(). Цикл закрывается в конце. Эта функция должна использоваться в качестве основной точки входа для программ asyncio и, желательно, вызываться только один раз. Рекомендуется использовать loop_factory для настройки цикла событий вместо политик. Передачаasyncio.EventLoopпозволяет запускать asyncio без системы политик.Исполнителю даётся таймаут в 5 минут для завершения. Если исполнитель не завершится в течение этого времени, выводится предупреждение, и исполнитель закрывается.
Пример:
async def main(): await asyncio.sleep(1) print('hello') asyncio.run(main())Добавлена в версии 3.7.
Изменена в версии 3.9: Обновлено для использования
loop.shutdown_default_executor().Изменена в версии 3.10: debug установлено по умолчанию в
Noneдля соблюдения глобальных настроек отладочного режима.Изменена в версии 3.12: Добавлен параметр loop_factory.
Менеджер контекста потокового обработчика
-
class asyncio.Runner(*, debug=None, loop_factory=None) -
Менеджер контекста, который упрощает многократные вызовы асинхронных функций в одном контексте.
Иногда несколько функций высшего уровня async должны вызываться в одном цикле событий и
contextvars.Context.Если debug равно
True, цикл событий будет запущен в отладочном режиме.Falseявным образом отключает отладочный режим.Noneиспользуется для соблюдения глобальных настроек Отладочного режима.loop_factory можно использовать для переопределения создания цикла. Ответственность loop_factory состоит в том, чтобы установить созданный цикл в качестве текущего. По умолчанию используется
asyncio.new_event_loop()и устанавливается в качестве текущего цикла событий с помощьюasyncio.set_event_loop(), если loop_factory равенNone.В принципе, пример
asyncio.run()можно переписать с использованием обработчика:async def main(): await asyncio.sleep(1) print('hello') with asyncio.Runner() as runner: runner.run(main())Добавлена в версии 3.11.
-
run(coro, *, context=None) -
Запустить корутину coro в встроенном цикле.
Вернуть результат корутины или вызвать её исключение.
Необязательный ключевой параметр context позволяет указать пользовательский
contextvars.Contextдля запуска coro в нём. Используется контекст по умолчанию обработчика, еслиNone.Эта функция не может быть вызвана, когда другой цикл событий asyncio работает в том же потоке.
-
close() -
Закрыть обработчик.
Завершить асинхронные генераторы, остановить исполнитель по умолчанию, закрыть цикл событий и освободить встроенный
contextvars.Context.
-
get_loop() -
Вернуть цикл событий, связанный с экземпляром обработчика.
Примечание
Runnerиспользует стратегию ленивой инициализации, её конструктор не инициализирует лежащие в основе низкоуровневые структуры.Встроенные loop и context создаются при входе в тело
withили при первом вызовеrun()илиget_loop(). -
Обработка прерывания клавиатурой
Добавлена в версии 3.11.
Когда signal.SIGINT генерируется нажатием Ctrl-C, исключение KeyboardInterrupt генерируется в основном потоке по умолчанию. Однако это не работает с asyncio, поскольку оно может прервать внутренние механизмы asyncio и заблокировать завершение программы.
Чтобы решить эту проблему, asyncio обрабатывает signal.SIGINT следующим образом:
-
asyncio.Runner.run()устанавливает пользовательский обработчикsignal.SIGINTперед выполнением любого пользовательского кода и удаляет его при выходе из функции. - Обработчик
Runnerсоздаёт главную задачу для переданной корутины для её выполнения. - Когда
signal.SIGINTгенерируется нажатием Ctrl-C, пользовательский обработчик сигнала отменяет главную задачу, вызвавasyncio.Task.cancel(), который генерируетasyncio.CancelledErrorвнутри главной задачи. Это заставляет стек Python развернуться,try/exceptиtry/finallyблоки могут использоваться для очистки ресурсов. После отмены главной задачиasyncio.Runner.run()генерируетKeyboardInterrupt. - Пользователь может написать узкий цикл, который не может быть прерван с помощью
asyncio.Task.cancel(), в этом случае второе нажатие Ctrl-C сразу генерируетKeyboardInterruptбез отмены главной задачи.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/asyncio-runner.html