Учебник Конкурентность и многопоточность для начинающих
Этот курс объясняет, как программы делают несколько дел «одновременно»: что такое процесс и поток, чем конкурентность отличается от параллелизма, как возникают состояния гонки и взаимные блокировки и как их предотвращать. На примерах Python вы разберётесь, почему GIL мешает потокам ускорять вычисления, когда выбирать threading, multiprocessing или asyncio, и освоите практические паттерны вроде producer-consumer и пула задач. Курс для тех, кто уже пишет на Python и хочет понимать многопоточность не на уровне заклинаний, а по-настоящему.
Курс «Конкурентность и многопоточность» состоит из 6 разделов и 18 уроков: Основы: процессы, потоки и конкурентность, Общая память и состояния гонки, Взаимные блокировки и живучесть, Python: GIL, потоки и процессы, Асинхронность и модели конкурентности и Практика: атомарность и паттерны. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Основы: процессы, потоки и конкурентность
- Процесс и поток: в чём разница
Что такое процесс и поток, как они связаны, что они разделяют, а что у каждого своё. Зачем нужны потоки внутри процесса.
- Конкурентность и параллелизм: важная разница
Конкурентность — про структуру и переключение задач, параллелизм — про одновременное выполнение на нескольких ядрах. Разбираем разницу.
- Как ОС планирует потоки и переключает контекст
Планировщик ОС, кванты времени, вытесняющая многозадачность и контекстное переключение: как процессор делится между потоками.
- Процесс и поток: в чём разница
2 Общая память и состояния гонки
- Состояние гонки (race condition)
Что такое состояние гонки, почему счётчик теряет значения и как недетерминированное переключение потоков ломает программу.
- Критическая секция и взаимное исключение (mutex/lock)
Критическая секция, взаимное исключение, мьютекс и блокировка: как защитить общие данные, чтобы их трогал только один поток.
- Семафоры и условные переменные
Семафор ограничивает число потоков в ресурсе, условная переменная усыпляет поток до сигнала. Разбираем оба примитива синхронизации.
- Состояние гонки (race condition)
3 Взаимные блокировки и живучесть
- Взаимная блокировка (deadlock) и условия Коффмана
Что такое deadlock, четыре условия Коффмана для его возникновения и как упорядочивание блокировок предотвращает зависание потоков.
- Livelock и голодание (starvation)
Livelock — потоки активны, но не продвигаются; starvation — поток не получает ресурса. Чем они отличаются от deadlock и как лечатся.
- Как отлаживать и предотвращать проблемы синхронизации
Практические приёмы против гонок и тупиков: таймауты, минимум общего состояния, неизменяемость, очереди вместо общих переменных.
- Взаимная блокировка (deadlock) и условия Коффмана
4 Python: GIL, потоки и процессы
- GIL: почему потоки не ускоряют вычисления
Global Interpreter Lock в CPython: что это, почему он есть, и почему многопоточный CPU-bound код в Python не ускоряется.
- Когда threading всё-таки полезен (I/O-bound)
Почему потоки в Python отлично подходят для I/O-bound задач: GIL отпускается во время ожидания сети и диска, и потоки реально перекрываются.
- Multiprocessing: процессы для CPU-задач
Как multiprocessing обходит GIL: каждый процесс со своим интерпретатором даёт настоящий параллелизм для тяжёлых вычислений в Python.
- GIL: почему потоки не ускоряют вычисления
5 Асинхронность и модели конкурентности
- Event loop, async/await и корутины
Как устроена асинхронность в Python: event loop, корутины, async/await и кооперативная многозадачность в одном потоке.
- Модели конкурентности: потоки, события, акторы, CSP
Обзор моделей конкурентности: разделяемая память с потоками, событийная модель, акторы с почтовыми ящиками и CSP с каналами.
- Пулы потоков и процессов
Зачем нужны пулы потоков и процессов, как ThreadPoolExecutor и ProcessPoolExecutor переиспользуют воркеров и ограничивают параллелизм.
- Event loop, async/await и корутины
6 Практика: атомарность и паттерны
- Атомарность и неблокирующие структуры
Что такое атомарная операция, как compare-and-swap позволяет работать без блокировок и почему lock-free структуры сложны, но быстры.
- Паттерн producer-consumer и очередь задач
Паттерн producer-consumer: производители кладут задачи в очередь, потребители разбирают. Развязка скоростей и буферизация через очередь.
- Типичные баги конкурентного кода и как их избегать
Сводка частых ошибок многопоточности: гонки, deadlock, проверка-затем-действие, неатомарность и практические правила их предотвращения.
- Атомарность и неблокирующие структуры