🐍🔀 Под капотом asyncio: принципы работы и ключевые концепции

Библиотека asyncio предоставляет полный набор инструментов для организации параллельного выполнения кода в Python с использованием концепции асинхронности. Но как на самом деле работает asyncio? Давайте разберемся в ключевых принципах и понятиях.

Этот материал взят из нашей субботней email-рассылки, посвященной Python. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

Asyncio – библиотека, которая предоставляет инфраструктуру для написания параллельного кода с использованием концепции асинхронного программирования. Она позволяет эффективно обрабатывать многочисленные задачи ввода-вывода (например, сетевые операции или чтение/запись из файлов) без необходимости создавать множество потоков или процессов. Ключевые концепции asyncio:

Событийный цикл (Event Loop)

  • Это ядро asyncio, которое отвечает за планирование и выполнение задач (корутин).
  • Реализован на языке C для максимальной эффективности.
  • Работает по принципу однопоточной многозадачности (single-threaded concurrency).
  • Постоянно опрашивает очередь событий и выполняет соответствующие задачи.

Корутины (Coroutines)

  • Это специальные функции, выполнение которых можно приостанавливать на определенных точках с помощью ключевого слова await.
  • Используются для написания асинхронного, событийно-ориентированного кода.
  • Могут ждать асинхронные события (ввод-вывод, сигналы или другие корутины).
  • Определяются с помощью async def.

Задачи (Tasks)

  • Представляют собой обертки над корутинами для их планирования и выполнения.
  • Создаются с помощью asyncio.create_task(coroutine) или asyncio.ensure_future(coroutine).
  • Задачи можно отменять, объединять с другими задачами и отслеживать на предмет исключений.
  • Задачи добавляются в событийный цикл и выполняются в порядке их готовности.
🐍 Библиотека питониста
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»
🐍💼 Библиотека собеса по Python
Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python»
🧩🐍 Библиотека задач по Python
Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Будущие объекты (Futures)

  • Представляют результат асинхронной операции, который может быть доступен позже.
  • Задачи наследуются от класса Future и добавляют собственные методы управления.
  • Могут быть использованы для координации между разными частями программы.

Транспорты и протоколы

  • Транспорты (sockets) отвечают за передачу данных по сети.
  • Протоколы определяют, как интерпретировать эти данные (HTTP, WebSocket и др.).
  • asyncio предоставляет высокоуровневые абстракции для работы с транспортами и протоколами.

Другие инструменты

  • Пулы для управления ограниченными ресурсами (потоки, подпроцессы).
  • Синхронизаторы для координации между корутинами (Lock, Event, Condition).
  • Очереди для безопасной передачи данных между корутинами.
  • Сигналы для обработки внешних событий (UNIX-сигналы).

Вот как работает asyncio:

  • Создается событийный цикл, который будет управлять выполнением задач.
  • Определяются корутины, которые выполняют некоторую работу и могут приостанавливаться на операциях ввода-вывода с помощью ключевого слова await.
  • Корутины оборачиваются в задачи с помощью функции asyncio.create_task().
  • Задачи планируются для выполнения в событийном цикле с помощью функции asyncio.run() или добавляются в цикл вручную.
  • Событийный цикл начинает выполнять задачи по очереди. Когда задача достигает операции ввода-вывода (например, await asyncio.sleep()), она приостанавливается, и событийный цикл переключается на другую задачу.
  • Когда операция ввода-вывода завершается, задача возобновляется и продолжает выполнение до следующей операции ввода-вывода или завершения.

Так asyncio позволяет эффективно использовать один поток для выполнения множества задач с операциями ввода-вывода, избегая блокировки и простоев из-за ожидания завершения этих операций.

Важно отметить, что asyncio оптимален именно для I/O-bound задач (сеть, файловые операции и т. д.), и не подходит для CPU-bound операций (вычислительно-интенсивных задач), поскольку в этом случае он не сможет переключаться на другие задачи во время блокировки. Для такого рода задач лучше использовать многопоточность или многопроцессорность. Подробнее о принципах работы asyncio – в этой статье и в этом видео.

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 декабря 2018

ООП на Python: концепции, принципы и примеры реализации

Программирование на Python допускает различные методологии, но в его основе...
admin
28 июня 2018

3 самых важных сферы применения Python: возможности языка

Существует множество областей применения Python, но в некоторых он особенно...
admin
13 февраля 2017

Программирование на Python: от новичка до профессионала

Пошаговая инструкция для всех, кто хочет изучить программирование на Python...