Перейти к содержанию

Параллелизм: Многопроцессность

Начало урока

Параллелизм: Многопроцессность

Задействуйте все ядра процессора, запуская настоящие отдельные процессы Python

Главная идея: Модуль multiprocessing запускает ваш код в отдельных процессах операционной системы, у каждого из которых свой интерпретатор Python и своя глобальная блокировка интерпретатора (GIL). Это единственный надёжный способ заставить CPU-bound (нагруженный вычислениями) код Python работать сразу на многих ядрах. Плата за это в том, что процессы не разделяют память, поэтому каждый аргумент и каждый результат должны быть сериализованы (pickle) и переправлены через границу процесса.
К концу урока вы сможете:
  • объяснить, почему GIL заставляет использовать процессы (а не потоки) для вычислительной работы,
  • запускать задачи через Process, Pool и ProcessPoolExecutor,
  • выбирать между map, imap и apply_async и подбирать разумный chunksize,
  • передавать данные с помощью Queue, Pipe и shared_memory,
  • избегать классических ловушек: защита if __name__ == "__main__", несериализуемые аргументы и методы запуска (spawn против fork).

1. GIL и почему потоки не ускоряют вычисления

CPython защищает своё внутреннее состояние глобальной блокировкой интерпретатора (GIL): в любой момент только один поток может выполнять байт-код Python. Для I/O-bound работы (ожидание сети, диска или базы данных) потоки прекрасны, потому что поток освобождает GIL, пока ждёт. Но для CPU-bound работы (вычисления, разбор, сжатие, обработка изображений) потоки лишь сменяют друг друга на одном ядре и не дают никакого ускорения.

Многопроцессность полностью обходит GIL. Каждый дочерний процесс — это отдельный интерпретатор Python со своим GIL, поэтому N процессов действительно могут выполнять байт-код Python на N ядрах одновременно.

Тип нагрузкиЛучший инструментПочему
I/O-bound (запросы, файлы, БД)threading / asyncioGIL освобождается во время ожидания; лишние процессы не нужны
CPU-bound (математика, разбор, кодирование)multiprocessingтолько отдельные процессы обходят узкое место единого GIL

Правило: если код занят вычислениями — берите процессы. Если он занят ожиданием — берите потоки или async.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя