Понимание shared_memory в Python 3.8 - PullRequest
10 голосов
/ 03 июля 2019

Я пытаюсь понять некоторые операции shared_memory.

Глядя на источник , похоже, что модуль использует shm_open() для сред UNIX и CreateFileMapping \ OpenFileMapping в окнах в сочетании с mmap.

Я понимаю из здесь , что во избежание тщательной сериализации / десериализации с помощью pickle необходимо явно реализовать __setstate__() и __getstate__() для его общего типа данных.

Я не вижу такой реализации в shared_memory.py.

Как shared_memory обойти обработку рассола?

Кроме того, на машине с Windows это, похоже, выживает среди переводчиков:

from mmap import mmap

shared_size = 12
shared_label = "my_mem"

mmap(-1, shared_size , shared_label)

Почему тогда CreateFileMapping \ OpenFileMapping здесь нужно?

1 Ответ

3 голосов
/ 12 июля 2019

Как shared_memory обойти обработку рассола?

Мне кажется, вы путаете общих типов и общих объектов между процессами.

Во-первых, вам не нужно использовать механизмы совместного использования, предоставляемые multiprocessing, чтобы получить общие объекты, вы можете просто обернуть базовые примитивы, такие как mmap / Windows-эквивалент или получить более изящные, используя любойAPI, предоставляемый вашей ОС / ядром.

Далее, вторая ссылка, о которой вы упомянули в отношении того, как выполняется копирование и как __getstate__ определяет поведение процесса засолки, зависит от вас - с помощью API модуля sharedctypes,Вы не обязаны выполнять выборку для разделения памяти между двумя процессами.

Фактически, sharedctypes поддерживается анонимной общей памятью, которая использует: https://github.com/python/cpython/blob/master/Lib/multiprocessing/heap.py#L31

Обе реализации опираются на mmap -подобный примитив.

В любом случае, если вы попытаетесь скопировать что-либо, используя sharedctype, вы получите:

И эта функция использует ForkingPickler, которая будет использовать pickle, а затем ... в конечном счете, вы будете вызывать __getstate__ где-нибудь.

Но это не относится к shared_memory, потому что shared_memory на самом деле не ctype -подобный объект.

У вас есть другие способы обмена объектами между процессами, используя Resource Sharer / TrackerAPI: https://github.com/python/cpython/blob/master/Lib/multiprocessing/resource_sharer.py, который будет опираться на pickle сериализацию / десериализацию.

Но вы не разделяете разделяемую память через разделяемую память, верно?

Когда вы используете: https://github.com/python/cpython/blob/master/Lib/multiprocessing/shared_memory.py

Вы создаете блок памяти с уникальным именем, и все процессы должны иметь уникальное имя до совместного использования памяти, иначе вы не сможете прикрепить ее.

По сути, аналогия такова:

У вас есть группа друзей, и выу всех есть уникальная секретная база, где только у вас есть локация, вы будете выполнять поручения, будете далеко друг от друга, но вы все можете встретиться в этом уникальном месте.

Для того, чтобы это сработалоВы должны все знать местоположение, прежде чем уходить друг от друга.Если у вас его нет заранее, вы не уверены, что сможете найти место для их встречи.

То же самое с shared_memory, вам нужно только его имя, чтобы открыть его.,Вы не разделяете / не передаете shared_memory между процессами.Вы прочитали shared_memory, используя его уникальное имя из нескольких процессов.

В результате чего вы его засолите?Вы можете.Вы можете абсолютно мариновать это.Но это может быть не встроенным, потому что просто отправить уникальное имя всем вашим процессам через другой канал совместно используемой памяти или что-то в этом роде.

Здесь не требуется никаких обходных путей.ShareableList это просто пример применения класса SharedMemory.Как вы можете видеть здесь: https://github.com/python/cpython/blob/master/Lib/multiprocessing/shared_memory.py#L314

Требуется что-то похожее на уникальное имя, вы также можете использовать анонимную разделяемую память и позже передать ее имя через другой канал (написать временный файл, отправить его обратно накакой-нибудь API, что угодно).

Почему тогда здесь необходим CreateFileMapping \ OpenFileMapping?

Поскольку это зависит от вашего интерпретатора Python, здесь вы можете использовать CPython, которыйвыполняет следующие действия:

https://github.com/python/cpython/blob/master/Modules/mmapmodule.c#L1440

Он уже косвенно использует CreateFileMapping, поэтому выполнение CreateFileMapping и его подключение просто дублируют уже выполненную работу в CPython.

Но как насчет других переводчиков?Все ли переводчики выполняют все необходимые функции для работы mmap на платформах, отличных от POSIX?Может быть, это обоснование для разработчика.

В любом случае, неудивительно, что mmap будет работать из коробки.

...