Cuplikan materi

Асинхронность и потоки в 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
Apa yang akan Anda pelajari dalam kuliah ini
  • Запускать сетевые задачи конкурентно
  • Управлять группой задач
  • Понимать, когда нужна сборка без GIL

Awal materi

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

  • Каждый запрос к 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 секунды

Materi lengkap tersedia dengan langganan

10 slide lagi di versi lengkap.

Video, semua slide, catatan, tes, tutor AI, dan wawancara terbuka setelah masuk dan berlangganan.

Masuk atau daftar Berlangganan

Isi materi

  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. Итог: курсы валют за секунду, расчёты — на всех ядрах

Artikel terkait materi ini

Semua materi kursus ini

  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 и итоговый проект