Развёрнутое пояснение:
1. Вызов await t(1) запускает первую корутину: на печать идёт 1, затем await sleep(0) приостанавливает выполнение main и отдаёт управление event loop.
2. create_task(t(3)) только планирует фоновую задачу в очередь event loop, но не запускает её немедленно.
3. await t(2) печатает 2 и тоже приостанавливается на sleep(0).
4. Event loop видит три готовых продолжения: t(1), запланированная t(3) и main после t(2). Порядок FIFO, поэтому сначала возобновляется t(1), которая печатает 2 и завершается.
5. Следующей запускается t(3): печатается 3, затем await sleep(0) приостанавливает её.
6. Затем event loop возвращает управление в main после await t(2), где сразу выполняется await x и main ждёт завершения t(3).
7. Event loop возобновляет t(3), печатается 4, задача завершается.
8. В результате на печать идёт последовательность 122334.
Почему это важно: в асинхронном коде побочные эффекты и порядок записи строк не всегда совпадают с порядком выполнения. sleep(0) — не пустая операция, а точка уступки управления, после которой event loop выбирает следующую задачу из очереди. Это влияет на порядок логов, обновление кэша, коммитов состояния и других операций с побочными эффектами, поэтому важно понимать, что create_task планирует задачу, а await передаёт управление.
Post #4840
500
Python: задачки и вопросы
- ✍ 2