MiddleКодЧастоЕщё не отвечали
Запустите три I/O-задачи конкурентно через asyncio
Допишите main, чтобы три вызова fetch перекрывались и завершались за ~1с, а не ~3с.
Требования:
- Запланировать все три корутины конкурентно на одном потоке.
- Напечатать список результатов после их завершения.
import asyncio
async def fetch(n):
await asyncio.sleep(1) # имитация I/O
return n * 2
async def main():
# ваш код здесь
...
asyncio.run(main())
Допишите реализацию.
Используйте asyncio.gather для конкурентного запуска корутин на одном потоке: await asyncio.gather(fetch(1), fetch(2), fetch(3)). await asyncio.sleep уступает управление, поэтому все три перекрываются и завершаются за ~1с, а не 3с. Блокирующий time.sleep застопорил бы цикл.
- ✗Ожидать каждую корутину последовательно, что сериализует их в ~3с
- ✗Использовать блокирующий
time.sleepвнутри корутины и стопорить цикл - ✗Вызывать
asyncio.runна каждую корутину вместо одногоgather
- →Почему блокирующий вызов вроде
time.sleepломает конкурентностьasyncio? - →Чем
asyncio.gatherотличается отasyncio.as_completed?
Оглавление
Задача
Реализуйте main, чтобы три I/O-задачи fetch выполнялись конкурентно и завершались примерно за одну секунду.
Решение
import asyncio
async def fetch(n):
await asyncio.sleep(1) # имитация I/O
return n * 2
async def main():
results = await asyncio.gather(fetch(1), fetch(2), fetch(3))
print(results) # [2, 4, 6] примерно через 1с, не 3с
asyncio.run(main())
Ключевые моменты
asyncio.gatherпланирует корутины конкурентно на одном потоке цикла событий.await asyncio.sleepуступает управление, позволяя трём ожиданиям перекрываться.- Блокирующий вызов (
time.sleep) застопорил бы весь цикл — нужны неблокирующие awaitable.
Оглавление