Вопрос с собеседования · Python

Как запустить несколько корутин одновременно и получить их результаты?

JuniorКонкурентность
Ещё спрашивают так:
  • Как сделать несколько HTTP-запросов параллельно в asyncio?
  • Что делает asyncio.run?
Коротко

Точка входа — asyncio.run(main()): создаёт цикл событий и выполняет корутину. Несколько корутин одновременно запускают asyncio.gather(a(), b(), c()) — результаты приходят в том же порядке, что и корутины; с Python 3.11 — asyncio.TaskGroup. Если писать await a(); await b() подряд, они выполнятся по очереди, без выигрыша.

  • Выигрыш есть только при ожидании ввода-вывода: сеть, диск, база
  • Ограничить число одновременных запросов — asyncio.Semaphore
  • Внутри корутин нужны асинхронные библиотеки: httpx, aiohttp, asyncpg

А ещё Вызов корутины без await ничего не выполняет — Python предупредит «coroutine was never awaited»

Подробно

Пример:

import asyncio, httpx

async def fetch(client, url):
    r = await client.get(url, timeout=10)
    return r.status_code

async def main(urls):
    async with httpx.AsyncClient() as client:
        return await asyncio.gather(*(fetch(client, u) for u in urls))

print(asyncio.run(main(["https://a.ru", "https://b.ru"])))

Десять запросов по секунде каждый займут около секунды, а не десять: пока один ждёт ответа, цикл переключается на другие.

Ограничение параллельности:

sem = asyncio.Semaphore(5)
async def limited(client, url):
    async with sem:
        return await fetch(client, url)

Что хотят услышать

  • asyncio.run как точка входа.
  • gather или TaskGroup для одновременного запуска.
  • Последовательные await не дают выигрыша.
  • Ограничение параллельности семафором.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓asyncio.gather или TaskGroup внутри asyncio.run; результаты gather идут в порядке корутин
  • ✗Написать await для каждой корутины подряд — они выполнятся одновременно, а результаты придут по готовности
  • ✗Вызвать корутины без await — они запустятся в фоне
  • ✗gather ускоряет вычисления на нескольких ядрах процессора

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования