Кому принадлежит память в потоках и процессах
Что проверяют
Понимаете ли вы разницу между изоляцией процессов и общей памятью потоков и как это выглядит именно в Python. Следом почти всегда спрашивают про GIL: делает ли он код потокобезопасным и зачем тогда threading.Lock.
Как отвечать
Владелец памяти это процесс. Операционная система выдаёт каждому процессу своё виртуальное адресное пространство, а потоки живут внутри него:
- общее у потоков: куча, глобальные переменные, открытые файлы. В CPython все объекты лежат в куче, поэтому любой поток видит тот же список или словарь, если у него есть ссылка;
- своё у потока: стек вызовов и регистры. В Python это значит, что локальные имена функции у каждого потока свои, но объект, на который они ссылаются, может быть общим. Для данных на поток есть
threading.local; - процессы: у каждого свой интерпретатор и своя куча. В
multiprocessingданные передаются черезQueueилиPipeс сериализациейpickle, а общая память выделяется явно:multiprocessing.shared_memory.SharedMemory,Value,Arrayили прокси черезManager.
Про GIL: он защищает внутренние структуры интерпретатора, например счётчики ссылок, но не вашу логику. counter += 1 состоит из нескольких операций байткода, и поток может переключиться между ними. Начиная с Python 3.13 есть сборка без GIL (free-threaded), в 3.14 она официально поддерживается, но по умолчанию по-прежнему ставится обычная.
Про fork: дочерний процесс получает копию памяти родителя по принципу copy-on-write, и изменения в одном процессе второй не видит. В CPython страницы копируются активнее, чем ожидают, потому что даже чтение объекта меняет его счётчик ссылок. С Python 3.14 на Linux метод запуска по умолчанию forkserver, на macOS и Windows это spawn.
Где спотыкаются
Говорят «раз есть GIL, гонок не бывает». Бывают, на любой операции «прочитать, изменить, записать».
Ждут, что изменение глобальной переменной в процессе из Pool станет видно родителю. Процесс работает со своей копией.
Передают в пул большие объекты, не думая о цене: каждый аргумент сериализуется через pickle и копируется в другой процесс, и это может стоить дороже самой задачи.