Запуск asyncio программ
Исходный код: 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 для настройки цикла событий вместо политик.Исполнитель получает таймаут в 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) -
Менеджер контекста, который упрощает вызовы нескольких асинхронных функций в одном контексте.
Иногда необходимо вызвать несколько основных асинхронных функций в одном цикле событий и
contextvars.Context.Если debug
True, цикл событий будет запущен в отладочном режиме.Falseявно отключает отладочный режим.Noneиспользуется для соблюдения глобальных настроек режима отладки.loop_factory может использоваться для переопределения создания цикла. Ответственность loop_factory — установить созданный цикл как текущий. По умолчанию используется
asyncio.new_event_loop()и устанавливается как текущий цикл событий с помощьюasyncio.set_event_loop(), если loop_factoryNone.В сущности, пример с
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.12/library/asyncio-runner.html