Безопасно ли ссылаться на экземпляры SharedMemory напрямую при использовании библиотеки multiprocessing.shared_memory в Python 3.8? - PullRequest
1 голос
/ 23 февраля 2020

Я начал использовать библиотеку multiprocessing.shared_memory, как описано в документации .

То есть я создаю массив numpy и записываю его в объект SharedMemory одним process:

import multiprocessing.managers
import numpy

a = numpy.array([1, 2, 3, 4, 5, 6])

smm = multiprocessing.managers.SharedMemoryManager()
smm.start()

sm = smm.SharedMemory(size=a.nbytes)

b = numpy.ndarray(a.shape, dtype=a.dtype, buffer=sm.buf)
b[:] = a[:]

print(sm.name)
psm_ad5d71e1

И в другом процессе я ссылаюсь на SharedMemory, используя его имя, и обращаюсь к массиву numpy таким образом:

import multiprocessing.shared_memory
import numpy
sm = multiprocessing.shared_memory.SharedMemory(name="psm_ad5d71e1")
c = numpy.ndarray((6,), dtype=numpy.int64, buffer=sm.buf)

print(c)
[1 2 3 4 5 6]

Пока все хорошо. Но в моем примере, когда массив numpy становится намного больше (размер в ГБ), интерпретатор продолжает умирать (поскольку он просто завершает работу, не выбрасывая никаких исключений), когда я разыменовываю массив numpy, созданный из объекта SharedMemory, то есть, линия print(c).

После долгого эксперимента я понял, что если я ссылаюсь на прямую MemoryObject, все работает, как ожидалось:

import multiprocessing.managers
import numpy
import pickle

a = numpy.array([1, 2, 3, 4, 5, 6])

smm = multiprocessing.managers.SharedMemoryManager()
smm.start()

sm = smm.SharedMemory(size=a.nbytes)

b = numpy.ndarray(a.shape, dtype=a.dtype, buffer=sm.buf)

b[:] = a[:]

with open('sm.pcl', 'wb') as f:
    pickle.dump(sm, f)

И в других вместо этого я делаю это:

import multiprocessing.shared_memory
import numpy
import pickle

with open('sm.pcl', 'rb') as f:
    sm = pickle.load(f)
c = numpy.ndarray((6,), dtype=numpy.int64, buffer=sm.buf)

print(c)
[1 2 3 4 5 6]

(В моем реальном примере я не pickle SharedMemory объект вручную, это делается автоматически, когда я передаю объект SharedMemory в аргументах в отдельный процесс.)

Так что мой вопрос просто, это безопасно? Или я использую библиотеку непреднамеренным (и небезопасным) способом?

Если бы я догадался, это должно быть безопасно, поскольку объект SharedMemory сам по себе является указателем. Поэтому я считаю, что это должно быть то же самое, что ссылаться на сам объект SharedMemory или ссылаться на него через атрибут name, используя функцию SharedMemory ...

Но я бы хотел, чтобы кто-то кто на самом деле знает комментарий! Заранее спасибо!

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