Spec-Zone.ru › Python 3.13

Средства запуска

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

В этом разделе описаны высокоуровневые примитивы asyncio для запуска кода asyncio.

Они построены на основе цикла событий и предназначены для упрощения использования асинхронного кода в распространённых сценариях.

  • Запуск программы asyncio
  • Контекстный менеджер Runner
  • Обработка прерывания с клавиатуры

Запуск программы 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.

Контекстный менеджер Runner

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() можно переписать, используя runner:

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, используется контекст runner по умолчанию.

Эту функцию нельзя вызывать, если в том же потоке уже выполняется другой цикл событий asyncio.

close()

Закрывает runner.

Завершает асинхронные генераторы, завершает работу исполнителя по умолчанию, закрывает цикл событий и освобождает встроенный contextvars.Context.

get_loop()

Возвращает цикл событий, связанный с экземпляром runner.

Примечание

Runner использует стратегию отложенной инициализации: его конструктор не инициализирует нижележащие низкоуровневые структуры.

Встроенные loop и context создаются при входе в тело with или при первом вызове run() либо get_loop().

Обработка прерывания с клавиатуры

Добавлено в версии 3.11.

Когда при нажатии Ctrl-C возникает signal.SIGINT, в главном потоке по умолчанию вызывается исключение KeyboardInterrupt. Однако это не работает с asyncio, поскольку может прервать внутренние механизмы asyncio и помешать завершению программы.

Чтобы смягчить эту проблему, asyncio обрабатывает signal.SIGINT следующим образом:

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

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/asyncio-runner.html

Spec-Zone.ru

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