Spec-Zone.ru › Python 3.12

Запуск asyncio программ

Исходный код: Lib/asyncio/runners.py

В этом разделе описаны высокоуровневые asyncio-примитивы для запуска 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_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 следующим образом:

  1. asyncio.Runner.run() устанавливает пользовательский обработчик signal.SIGINT перед выполнением любого пользовательского кода и удаляет его при выходе из функции.
  2. Менеджер запуска Runner создаёт основную задачу для выполнения переданной корутины.
  3. Когда signal.SIGINT генерируется нажатием Ctrl-C, пользовательский обработчик сигнала отменяет главную задачу, вызывая asyncio.Task.cancel(), что вызывает asyncio.CancelledError внутри главной задачи. Это заставляет стек Python развернуться, try/except и try/finally блоки могут использоваться для очистки ресурсов. После отмены главной задачи asyncio.Runner.run() поднимает KeyboardInterrupt.
  4. Пользователь может написать жёсткий цикл, который невозможно прервать с помощью 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API