Как работает механизм async/await в Python

Ответ

Механизм async/await в Python реализует кооперативную многозадачность с помощью корутин и цикла событий (event loop).

Ключевая идея — не блокировать основной поток на время ожидания операций ввода-вывода (I/O-bound tasks), а переключаться на выполнение других корутин.

Основные компоненты:

  1. Корутина (async def): Функция, объявленная с async def, при вызове возвращает объект корутины, а не выполняется немедленно. Она может приостанавливать свое выполнение.

  2. Оператор await: Приостанавливает выполнение текущей корутины, передавая управление обратно циклу событий. Цикл событий может запустить другую задачу. Когда ожидаемая операция (например, сетевой запрос) завершится, цикл возобновит выполнение приостановленной корутины.

  3. Цикл событий (Event Loop): Это ядро asyncio. Он управляет корутинами, отслеживает их состояние (готовы к выполнению, ожидают I/O) и переключает контекст между ними.

Пример работы:

import asyncio
import time

async def fetch_data():
    print("Начало загрузки данных...")
    # Имитация долгой I/O операции (например, запрос к API)
    await asyncio.sleep(2)
    print("Данные загружены.")
    return {"data": 123}

async def process_something_else():
    print("Начало другой задачи...")
    await asyncio.sleep(1)
    print("Другая задача завершена.")

async def main():
    start_time = time.time()
    # Запускаем обе корутины как задачи, чтобы они выполнялись конкурентно
    task1 = asyncio.create_task(fetch_data())
    task2 = asyncio.create_task(process_something_else())

    await task1
    await task2

    print(f"Все задачи выполнены за {time.time() - start_time:.2f} секунд")

# Запускает event loop и выполняет корутину main
asyncio.run(main())

# Вывод покажет, что общее время выполнения ~2 секунды, а не 3 (2+1),
# так как задачи выполнялись конкурентно.