Sehemu ya muhadhara

Асинхронность и потоки в Python: asyncio, TaskGroup и free-threading

Зачем нужна конкурентность, async/await, TaskGroup, потоки и GIL. Для опытных: TaskGroup.cancel (3.15), free-threaded сборка (3.13–3.14), субинтерпретаторы (3.14).

asyncio TaskGroup GIL free-threading
Utakachojifunza katika muhadhara huu
  • Запускать сетевые задачи конкурентно
  • Управлять группой задач
  • Понимать, когда нужна сборка без GIL

Mwanzo wa muhadhara

Три курса валют — три секунды ожидания

  • Каждый запрос к API курсов ≈ 1 с ожидания сети
  • Подряд: 3.0 с, вместе: 1.0 с
  • Процессор всё это время простаивает

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

$ uv run rates_seq.py
подряд 3.0 с

$ uv run rates_async.py
вместе 1.0 с

Ждать и считать — разные задачи

  • I/O-bound: сеть, диск, база — ждём ответа
  • CPU-bound: расчёты — процессор занят
  • Для ожидания — asyncio или потоки, для расчётов — процессы

Сначала главное различие, без которого дальше ничего не понять. Представьте повара. Если он поставил воду и ждёт кипения, он может за это время нарезать овощи, а потом поставить духовку — один повар, много дел, потому что основное время занимает ожидание. Это задачи ввода-вывода: сеть, диск, база данных. А если он вручную месит тесто, параллельно ничего не сделаешь — руки заняты. Это вычислительные задачи. Для них нужны дополнительные повара.

async и await: функция, которая умеет ждать

  • async def — корутина: вызов не выполняет, а создаёт объект
  • await — «подожди, а пока займись другим»
  • asyncio.run(main()) — запустить цикл событий

Асинхронный код в Python строится на двух словах. Async перед def объявляет корутину — функцию, которая умеет приостанавливаться. Await внутри неё говорит: здесь я буду ждать, а ты, цикл событий, пока займись другими задачами. Тот самый повар: поставил воду, сказал await и пошёл резать овощи. Запускается всё это функцией run. Важная деталь: внутри асинхронного кода нельзя пользоваться обычным sleep или блокирующими запросами — они остановят весь цикл.

import asyncio

async def fetch_rate(currency: str) -> float:
    await asyncio.sleep(1)          # имитация запроса к API
    return 90.0

async def main() -> None:
    for cur in ["USD", "EUR", "CNY"]:
        rate = await fetch_rate(cur)  # ждём по очереди
        print(cur, rate)

asyncio.run(main())                 # ~3 секунды

Muhadhara kamili unapatikana kwa usajili

Kuna slaidi 10 zaidi katika toleo kamili.

Video, slaidi zote, maelezo, majaribio, AI tutor na mahojiano vitafunguka baada ya kuingia na kujisajili.

Ingia au jisajili Jiandikishe

Yaliyomo kwenye muhadhara

  1. Три курса валют — три секунды ожидания
  2. Ждать и считать — разные задачи
  3. async и await: функция, которая умеет ждать
  4. TaskGroup: запустить вместе и дождаться всех
  5. Ошибка в одной задаче отменяет остальные
  6. Грабли: забыли await
  7. GIL: почему потоки не ускоряют расчёты
  8. ❓ Стоп-проверка: что выбрать?
  9. 💡 Разбор: ждём — asyncio или потоки, считаем — процессы
  10. Что нового: TaskGroup.cancel (3.15)
  11. Что нового: Python без GIL (3.13–3.14, PEP 703 и 779)
  12. Что нового: субинтерпретаторы (3.14, PEP 734)
  13. Итог: курсы валют за секунду, расчёты — на всех ядрах

Makala kuhusu somo hili

Mihadhara yote ya kozi hii

  1. Python 3.15 с нуля и для опытных: что нового и как учить
  2. Python 3.15: установка, REPL и первый скрипт за десять минут
  3. Переменные, числа и строки в Python: f-строки и t-строки
  4. Условия, циклы и match/case в Python: управляем ходом программы
  5. Списки, кортежи, словари и множества: frozendict в Python 3.15
  6. Comprehensions в Python: распаковка * и ** внутри (PEP 798)
  7. Функции и аннотации типов в Python: от def до sentinel
  8. Ошибки и исключения в Python 3.15: читаем трейсбек и подсказки «Did you mean»
  9. Модули, пакеты и ленивые импорты в Python 3.15 (PEP 810)
  10. Файлы, JSON и CSV в Python: pathlib и UTF-8 по умолчанию
  11. Классы и dataclasses в Python: ООП без лишнего кода
  12. Асинхронность и потоки в Python: asyncio, TaskGroup и free-threading
  13. Профилирование Python 3.15: Tachyon вместо cProfile и итоговый проект