# asyncio

> Модуль стандартной библиотеки Python для асинхронного ввода-вывода на основе цикла событий и сопрограмм async/await.

Источник: https://llmdocs.ru/wiki/asyncio/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Тип**: модуль стандартной библиотеки
- **Язык**: Python
- **Появился в**: Python 3.4 (2014)
- **Основные PEP**: PEP 3156, PEP 492
- **Модель**: однопоточный цикл событий, кооперативная многозадачность
- **Альтернативы**: Trio, AnyIO, gevent
- **Документация**: [docs.python.org/3/library/asyncio](https://docs.python.org/3/library/asyncio.html)
**asyncio** — модуль стандартной библиотеки [Python](https://llmdocs.ru/wiki/python.md) для написания конкурентного кода с помощью синтаксиса `async`/`await`. Он реализует цикл событий (event loop), который в одном потоке переключается между множеством задач, пока те ждут ввода-вывода: ответа сети, базы данных, файла. asyncio лежит в основе асинхронных веб-фреймворков ([FastAPI](https://llmdocs.ru/wiki/fastapi.md), aiohttp), драйверов баз данных и многих клиентов API.

## История

До asyncio асинхронный ввод-вывод в Python обеспечивали сторонние библиотеки — Twisted, Tornado, gevent — с несовместимыми между собой моделями. В 2012 году Гвидо ван Россум предложил единый стандарт (PEP 3156, кодовое имя Tulip), и в Python 3.4 (2014) модуль вошёл в стандартную библиотеку.[2] Первоначально сопрограммы писались на генераторах с `yield from`.

В Python 3.5 появились ключевые слова `async def` и `await` (PEP 492),[3] сделав сопрограммы отдельной сущностью языка. Дальнейшие важные изменения:

- 3.7 — функция `asyncio.run()`, ставшая стандартной точкой входа;
- 3.9 — `asyncio.to_thread()` для вызова блокирующего кода в потоке;
- 3.11 — `TaskGroup` и `asyncio.timeout()`, структурированная конкурентность.[4]

## Основные понятия

**Сопрограмма** (coroutine) — функция, объявленная через `async def`. Её вызов не выполняет код, а возвращает объект-сопрограмму; выполнение начинается, когда её ожидают через `await` или оборачивают в задачу.

**Цикл событий** — планировщик, который хранит готовые к выполнению задачи и следит за сокетами через механизмы ОС (epoll, kqueue, IOCP). Когда задача доходит до `await` на незавершённой операции, она добровольно отдаёт управление, и цикл запускает следующую. Это **кооперативная** многозадачность: переключение происходит только в точках `await`.

**Задача** (Task) — сопрограмма, запущенная в цикле событий конкурентно с другими (`asyncio.create_task()`).

**Future** — низкоуровневый объект «результат появится позже»; задачи являются его подклассом.

## Пример

```python
import asyncio
import time

async def fetch(name: str, delay: float) -> str:
    await asyncio.sleep(delay)          # имитация сетевого запроса
    return f"{name}: готово за {delay} с"

async def main() -> None:
    start = time.perf_counter()
    async with asyncio.TaskGroup() as tg:   # Python 3.11+
        tasks = [tg.create_task(fetch(f"запрос {i}", 1.0)) for i in range(3)]
    for t in tasks:
        print(t.result())
    print(f"всего: {time.perf_counter() - start:.1f} с")  # ≈ 1.0, а не 3.0

asyncio.run(main())
```

Три «запроса» по одной секунде выполняются примерно за секунду, потому что ожидание перекрывается. Если одна из задач в `TaskGroup` завершится исключением, остальные будут отменены, а ошибки собраны в `ExceptionGroup`.

## Инструменты модуля

| Средство | Назначение |
|---|---|
| `asyncio.gather()` | дождаться нескольких awaitable и собрать результаты |
| `asyncio.TaskGroup` | структурированный запуск группы задач с отменой при ошибке |
| `asyncio.timeout()`, `wait_for()` | ограничение времени ожидания |
| `asyncio.Queue` | очередь производитель — потребитель |
| `asyncio.Semaphore`, `Lock`, `Event` | примитивы синхронизации |
| `asyncio.to_thread()` | выполнить блокирующую функцию в отдельном потоке |
| `loop.run_in_executor()` | то же для пула потоков или процессов |
| потоки (`open_connection`) | высокоуровневая работа с TCP |

## Типичные ошибки

- **Блокирующий вызов внутри сопрограммы.** `time.sleep()`, синхронный HTTP-клиент или тяжёлый расчёт останавливают весь цикл событий. Их нужно заменять асинхронными аналогами или выносить в `to_thread()`.
- **Забытый `await`.** Вызов сопрограммы без `await` ничего не делает; Python выдаёт предупреждение «coroutine was never awaited».
- **Потерянные задачи.** Задача, созданная `create_task()` без сохранения ссылки, может быть удалена сборщиком мусора; документация рекомендует хранить ссылки или использовать `TaskGroup`.[1]
- **Ожидание ускорения расчётов.** asyncio не распараллеливает вычисления на ядра процессора — для этого нужны процессы или сборка без GIL (см. [GIL и free-threading (PEP 703)](https://llmdocs.ru/wiki/gil-free-threading.md)).

Режим отладки (`asyncio.run(main(), debug=True)` или переменная окружения `PYTHONASYNCIODEBUG=1`) сообщает о медленных обратных вызовах и неожиданных сопрограммах.[5]

## asyncio, потоки и процессы

| Подход | Когда подходит |
|---|---|
| asyncio | тысячи одновременных сетевых соединений, I/O-нагрузка |
| потоки (`threading`) | умеренное число блокирующих операций, совместимость со старыми библиотеками |
| процессы (`multiprocessing`) | вычисления на нескольких ядрах |

Подробнее о различии понятий — в статье [Конкурентность и параллелизм](https://llmdocs.ru/wiki/concurrency-parallelism.md).

## Альтернативы

**Trio** предложил идею «детских садов» (nurseries) — предшественника `TaskGroup`. **AnyIO** даёт единый API поверх asyncio и Trio. **uvloop** — замена стандартного цикла событий на основе libuv, ускоряющая сетевой код.

## См. также

- [Python](https://llmdocs.ru/wiki/python.md)
- [Генераторы и итераторы](https://llmdocs.ru/wiki/generators-iterators.md)
- [Промисы и async/await (JS)](https://llmdocs.ru/wiki/js-promises-async.md)
- [Конкурентность и параллелизм](https://llmdocs.ru/wiki/concurrency-parallelism.md)

## Источники

1. [asyncio — Asynchronous I/O (Python documentation)](https://docs.python.org/3/library/asyncio.html)
2. [PEP 3156 — Asynchronous IO Support Rebooted: the asyncio Module](https://peps.python.org/pep-3156/)
3. [PEP 492 — Coroutines with async and await syntax](https://peps.python.org/pep-0492/)
4. [Coroutines and Tasks — Task Groups](https://docs.python.org/3/library/asyncio-task.html#task-groups)
5. [Developing with asyncio](https://docs.python.org/3/library/asyncio-dev.html)
