From e5abc1fe99340b979b18864d978179f71fe8f5c5 Mon Sep 17 00:00:00 2001 From: vlapa Date: Sat, 13 Jun 2026 20:33:26 +0300 Subject: First --- PYTHON/AsyncIO.md | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 PYTHON/AsyncIO.md (limited to 'PYTHON/AsyncIO.md') diff --git a/PYTHON/AsyncIO.md b/PYTHON/AsyncIO.md new file mode 100644 index 0000000..2c8e365 --- /dev/null +++ b/PYTHON/AsyncIO.md @@ -0,0 +1,155 @@ +### Под капотом asyncio: принципы работы и ключевые концепции ### + +**Библиотека asyncio предоставляет полный набор инструментов для организации параллельного выполнения кода в Python с использованием концепции асинхронности. Но как на самом деле работает asyncio? Давайте разберемся в ключевых принципах и понятиях. + +Библиотека asyncio предоставляет полный набор инструментов для организации параллельного выполнения кода в Python с использованием концепции асинхронности. Но как на самом деле работает asyncio? Давайте разберемся в ключевых принципах и понятиях. + +Этот материал взят из нашей субботней [email-рассылки](https://proglib.io/w/edaee37b), посвященной Python. Подпишитесь, чтобы быть в числе первых, кто получит дайджест. + +**Asyncio** – библиотека, которая предоставляет инфраструктуру для написания параллельного кода с использованием концепции асинхронного программирования. Она позволяет эффективно обрабатывать многочисленные задачи ввода-вывода (например, сетевые операции или чтение/запись из файлов) без необходимости создавать множество потоков или процессов. Ключевые концепции asyncio: + +**Событийный цикл (Event Loop)** + +- Это ядро **asyncio**, которое отвечает за планирование и выполнение задач (корутин). +- Реализован на языке **C** для максимальной эффективности. +- Работает по принципу **однопоточной многозадачности** (single-threaded concurrency). +- Постоянно опрашивает очередь событий и выполняет соответствующие задачи. + +**Корутины (Coroutines)** + +- Это специальные функции, выполнение которых можно приостанавливать на определенных точках с помощью ключевого слова `await`. +- Используются для написания асинхронного, событийно-ориентированного кода. +- Могут ждать асинхронные события (ввод-вывод, сигналы или другие корутины). +- Определяются с помощью `async def`. + +**Задачи (Tasks)** + +- Представляют собой обертки над корутинами для их планирования и выполнения. +- Создаются с помощью `asyncio.create_task(coroutine)` или `asyncio.ensure_future(coroutine)`. +- Задачи можно отменять, объединять с другими задачами и отслеживать на предмет исключений. +- Задачи добавляются в событийный цикл и выполняются в порядке их готовности. + +**Будущие объекты (Futures)** + +- Представляют результат асинхронной операции, который может быть доступен позже. +- Задачи наследуются от класса `Future` и добавляют собственные методы управления. +- Могут быть использованы для координации между разными частями программы. + +**Транспорты и протоколы** + +- **Транспорты** (sockets) отвечают за **передачу** данных по сети. +- **Протоколы** определяют, как **интерпретировать** эти данные (HTTP, WebSocket и др.). +- asyncio предоставляет высокоуровневые абстракции для работы с транспортами и протоколами. + +**Другие инструменты** + +- Пулы для управления ограниченными ресурсами (потоки, подпроцессы). +- Синхронизаторы для координации между корутинами (**Lock****,** **Event**, **Condition)**. +- Очереди для безопасной передачи данных между корутинами. +- Сигналы для обработки внешних событий (UNIX-сигналы). + +**Вот как работает asyncio:** + +- Создается **событийный цикл**, который будет управлять выполнением задач. +- Определяются корутины, которые выполняют некоторую работу и могут приостанавливаться на операциях ввода-вывода с помощью ключевого слова `await`. +- Корутины оборачиваются в задачи с помощью функции `asyncio.create_task()`. +- Задачи планируются для выполнения в событийном цикле с помощью функции `asyncio.run()` или добавляются в цикл вручную. +- Событийный цикл начинает выполнять задачи по очереди. Когда задача достигает операции ввода-вывода (например, `await asyncio.sleep()`), она приостанавливается, и событийный цикл переключается на другую задачу. +- Когда операция ввода-вывода завершается, задача возобновляется и продолжает выполнение до следующей операции ввода-вывода или завершения.  + +Статья по теме + +[Упрощаем разработку: асинхронные функции Python](https://proglib.io/p/uproshchaem-razrabotku-asinhronnye-funkcii-python-2019-10-06) + +Так asyncio позволяет эффективно использовать **один** поток для выполнения **множества** задач с операциями ввода-вывода, избегая блокировки и простоев из-за ожидания завершения этих операций. + +Важно отметить, что asyncio оптимален **именно для I/O-bound задач** (сеть, файловые операции и т. д.), и **не подходит для CPU-bound операций** (вычислительно-интенсивных задач), поскольку в этом случае он не сможет переключаться на другие задачи во время блокировки. Для такого рода задач лучше использовать многопоточность или многопроцессорность. Подробнее о принципах работы asyncio – в [этой статье](https://jacobpadilla.com/articles/recreating-asyncio) и [в этом видео](https://www.youtube.com/watch?v=RIVcqT2OGPA)[](http://savefrom.net/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DRIVcqT2OGPA&utm_source=userjs-safari&utm_medium=extensions&utm_campaign=link_modifier "Получи прямую ссылку"). + +======================================= +🚀 **asyncio** – это библиотека для асинхронного программирования, позволяющая писать код, выполняющий несколько задач параллельно (без потоков и процессов). + +✅ async def – объявление асинхронной функции (корутина). +✅ await – приостанавливает выполнение до завершения асинхронной операции. +✅ asyncio.run() – запускает главную асинхронную функцию. +✅ asyncio.create_task() – запускает корутину в фоновом режиме. +✅ asyncio.sleep() – имитирует задержку без блокировки других задач. + +```python +import asyncio + +async def say_hello(): +    await asyncio.sleep(1)  # Имитация задержки +    print("Привет, мир!") + +async def main(): +    task1 = asyncio.create_task(say_hello()) +    task2 = asyncio.create_task(say_hello()) +    await task1 +    await task2 + +asyncio.run(main())  # Запуск асинхронной программы +``` +**Выведет с задержкой 1 секунду:** + +Привет, мир! +Привет, мир! + +Обе задачи выполняются **параллельно**, а не последовательно! + +📌 Когда использовать asyncio? + +✅ Запросы в интернет (aiohttp). +✅ Работа с базами данных (aiomysql, asyncpg). +✅ Асинхронное чтение файлов/сокетов. +✅ Многозадачность без потоков и процессов. + +#====================================== +**Вот как работает asyncio — без магии:** + +📌 1. **Event Loop — это «планировщик», который гоняет корутины. Он сам не создаёт потоки. Он ждёт, когда одна задача «освободит» CPU, и сразу берётся за другую.** +```python +import asyncio + +async def main(): +    print("Start") +    await asyncio.sleep(1) +    print("End") + +asyncio.run(main()) +``` +Здесь await asyncio.sleep(1) — не блокирует поток. Это ***yield*,** который говорит: "я пока жду, можешь заняться чем-то ещё". + +📌 2. **Ты не должен использовать time.sleep() в async-коде. Это блокирует весь event loop. Заменяй на await asyncio.sleep().** + +📌 3. **Любая синхронная тяжёлая операция — угроза. Например, чтение файла или SQL-запрос через обычный драйвер.** + +✔️ Как решить: + +👍 Используй aiofiles для файлов. +👍 Используй async-драйверы (asyncpg, aiomysql, httpx и т.д.) +👍 Если нет async-аналога — выноси в ThreadPoolExecutor. +```python +from concurrent.futures import ThreadPoolExecutor +import asyncio + +def blocking(): +    ... + +async def main(): +    loop = asyncio.get_running_loop() +    await loop.run_in_executor(None, blocking) +``` + +📌 4.**Не забывай про семафоры, если запускаешь 1000 задач одновременно. async не значит всё сразу.** +```python +sem = asyncio.Semaphore(100) + +async def safe_task(): +    async with sem: +        await do_something() +``` + +🧠 asyncio — это не про параллельность. Это про эффективное переключение задач, которые  ждут  чего-то: ответа сервера, данных, паузы. + +🗣 **Применяется в: Web-серверах (FastAPI, aiohttp), парсинге, бэкенде с I/O, высоконагруженных API.** + -- cgit v1.2.3