Получить доступ

Какие ограничения есть у multiprocessing и чем fork отличается от spawn?

MiddleКонкурентность
Ещё спрашивают так:
  • Почему ProcessPoolExecutor не принимает лямбду?
  • Как процессы в Python обмениваются данными?
Коротко

Процессы не делят память: аргументы и результаты сериализуются pickle и копируются. Лямбды, локальные функции, открытые файлы и соединения не сериализуются. fork копирует процесс родителя (быстро, но опасно с потоками), spawn запускает чистый интерпретатор и импортирует модуль заново (нужна защита if __name__ == "__main__").

  • По умолчанию: Linux — fork (с 3.14 — forkserver), macOS и Windows — spawn
  • Общие данные — Queue, Pipe, Manager, shared_memory
  • Большие данные гонять через pickle дорого — передавать пути или использовать shared_memory

А ещё fork после запуска потоков может унаследовать захваченную блокировку и зависнуть

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Почему pickle. Процесс — отдельное адресное пространство. Чтобы передать задачу, пул сериализует функцию (по имени модуля и функции) и аргументы, отправляет по каналу, а результат — обратно. Поэтому:

  • функция должна импортироваться по имени — не лямбда и не вложенная;
  • аргументы — сериализуемые (не сокеты, не соединения с БД, не генераторы);
  • каждое копирование стоит времени: мелкие задачи с большими данными выполняются медленнее, чем последовательно.

Методы запуска:

  • fork — копия родителя с его памятью (copy-on-write): быстрый старт, глобальные данные доступны. Опасен, если в родителе уже были потоки: в ребёнке остаётся только один поток, а блокировки, которые держали другие, — захваченными навсегда.
  • spawn — новый интерпретатор, модуль импортируется заново. Медленнее, зато предсказуемо. Код запуска — под if __name__ == "__main__":, иначе дети рекурсивно запускают пул.
  • forkserver — компромисс: форк от чистого серверного процесса.

Обмен данными: multiprocessing.Queue, Pipe, Manager (прокси к объектам в процессе-сервере, медленно), shared_memory (Python 3.8) — общий буфер без копирования, удобно с NumPy.

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

  • Отсутствие общей памяти и роль pickle.
  • Ограничения на функции и аргументы.
  • fork, spawn и их риски.

Частые ошибки

  • Запуск пула без if __name__ == "__main__".
  • Передача огромных объектов в каждую задачу.

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

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем