Когда происходит переключение между тасками в asyncio
Что проверяют
Понимаете ли вы, что многозадачность в asyncio кооперативная: цикл событий не может отобрать управление у задачи, она отдаёт его сама. Следом обычно спрашивают, что будет, если внутри корутины вызвать time.sleep или requests.get.
Как отвечать
Переключение происходит в одном случае: задача дошла до await на объекте, который ещё не готов, и реально приостановилась. Управление возвращается в цикл, и тот запускает следующую готовую задачу.
awaitна незавершённом future: сетевой ввод-вывод,asyncio.sleep, ожиданиеQueue.get, занятогоasyncio.Lock, другой задачи;awaitна корутине: сам по себе не переключает.await foo()выполняетfooв той же задаче, как обычный вызов, пока внутри не встретится настоящая приостановка;- готовый результат:
awaitна уже завершённом future или свободномLockотдаёт значение сразу, без захода в цикл; await asyncio.sleep(0): явный способ уступить управление на одну итерацию цикла;asyncio.create_task: не запускает корутину немедленно, а ставит её в очередь, она стартует на ближайшей итерации. Исключение: сasyncio.eager_task_factory(Python 3.12) задача сразу выполняется до первой приостановки;async withиasync for: переключают, только если их__aenter__или__anext__действительно ждут.
Отсюда важное следствие: код между двумя await выполняется атомарно относительно других задач того же цикла. А любой блокирующий вызов останавливает весь цикл: time.sleep, синхронный драйвер базы, тяжёлые вычисления. Их уводят в поток через asyncio.to_thread или в пул процессов через run_in_executor. Найти такие места помогает режим отладки asyncio.run(main(), debug=True): он пишет в лог шаги дольше 100 мс.
Где спотыкаются
Считают, что любой await отдаёт управление, и не понимают, почему цепочка вложенных корутин без реального ожидания держит цикл.
Верят, что asyncio читает файлы асинхронно. Обычный open().read() блокирует, для файлов нужен поток или библиотека вроде aiofiles.
Путают конкурентность с параллелизмом и ждут ускорения CPU-задач. Цикл событий работает в одном потоке, выигрыша на вычислениях не будет.