Как работают async и await?
- Что такое корутина?
- Что такое event loop?
- Как запустить несколько корутин одновременно?
async def создаёт корутину, await — точка, где она отдаёт управление циклу событий, пока ждёт.
- Цикл событий переключается между корутинами в точках
await— в одном потоке - Одновременный запуск:
asyncio.gatherилиasyncio.TaskGroup(3.11+)
А ещё Блокирующий вызов (time.sleep, синхронный HTTP) останавливает все корутины
Подробно
Вызов функции, объявленной через async def, не выполняет её тело, а возвращает объект-корутину. Выполнить его можно через await внутри другой корутины или запустив цикл событий: asyncio.run(main()).
Цикл событий (event loop) держит список задач. Корутина выполняется до ближайшего await на операции, которая ещё не готова (ответ сети, таймер). Там она приостанавливается, цикл запускает другую готовую задачу, а когда операция завершается — продолжает первую с того же места. Переключение кооперативное: корутина сама решает, где уступить, и только в await.
Одновременность. Последовательные await a(); await b() идут друг за другом. Чтобы задачи шли параллельно, их оборачивают в задачи: asyncio.gather(a(), b()), asyncio.create_task(...) или TaskGroup — последний правильно отменяет остальные задачи при ошибке.
Ограничения. await можно писать только внутри async def. Всё блокирующее внутри корутины останавливает цикл целиком: вместо time.sleep — asyncio.sleep, вместо requests — aiohttp или httpx. Блокирующий код, без которого не обойтись, выносят в поток: await asyncio.to_thread(func).
asyncio не ускоряет вычисления — это способ эффективно ждать много операций ввода-вывода.
Пример
import asyncio
async def fetch(name, delay):
await asyncio.sleep(delay) # не блокирует другие корутины
return f"{name} готов"
async def main():
# последовательно — 3 секунды
await fetch("a", 1)
await fetch("b", 2)
# параллельно — 2 секунды
results = await asyncio.gather(fetch("a", 1), fetch("b", 2))
print(results)
asyncio.run(main())Что хотят услышать
- Что такое корутина и что вызов
async defеё только создаёт. - Роль цикла событий и кооперативное переключение в
await. - Как запустить задачи параллельно.
- Опасность блокирующих вызовов и способ их вынести.
Частые ошибки
- Забыть
await— корутина не выполнится, будет предупреждение. - Ожидать, что asyncio ускорит вычисления на CPU.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗async def запускает функцию в отдельном потоке, а await ждёт её завершения
- ✓async def создаёт корутину, await — точка, где она отдаёт управление циклу событий
- ✗time.sleep внутри корутины отдаёт управление другим корутинам
- ✗await создаёт новый процесс для ожидания
Что спросят дальше
Разбор темы
- asyncio — корутины, задачи, отмена и блокирующий код
Как работают async и await, как запускать корутины одновременно, gather и TaskGroup, что делает блокирующий вызов в цикле событий, отмена и таймауты.
Связанные вопросы
- Что такое генератор и чем он полезен? Junior
- Что такое GIL? Junior
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.