(Python 多处理)如何访问与 multiprocessing.shared_memory.SharedMemory 共享的数组?

Posted

技术标签:

【中文标题】(Python 多处理)如何访问与 multiprocessing.shared_memory.SharedMemory 共享的数组?【英文标题】:(Python multiprocessing) How can I access an array shared with multiprocessing.shared_memory.SharedMemory? 【发布时间】:2021-10-24 22:48:35 【问题描述】:

我正在尝试了解 multiprocessing.shared_memory.SharedMemory 的工作原理。我尝试从https://docs.python.org/3/library/multiprocessing.shared_memory.html 运行第二个示例 - 但它似乎不像宣传的那样工作:

Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
>>> # In the first Python interactive shell
>>> import numpy as np
>>> a = np.array([1, 1, 2, 3, 5, 8])  # Start with an existing NumPy array
>>> from multiprocessing import shared_memory
>>> shm = shared_memory.SharedMemory(create=True, size=a.nbytes)
>>> # Now create a NumPy array backed by shared memory
>>> b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
>>> b[:] = a[:]  # Copy the original data into shared memory
>>> b
array([1, 1, 2, 3, 5, 8])
>>> type(b)
<class 'numpy.ndarray'>
>>> type(a)
<class 'numpy.ndarray'>
>>> shm.name
'wnsm_e3abbd9a'

到目前为止,一切都很好。但是,当我尝试在同一台机器上的相同或新 Python shell 中访问此共享数组时,就会出现问题:

>>> # In either the same shell or a new Python shell on the same machine
>>> import numpy as np
>>> from multiprocessing import shared_memory
>>> # Attach to the existing shared memory block
>>> existing_shm = shared_memory.SharedMemory(name='wnsm_e3abbd9a')
>>> # Note that a.shape is (6,) and a.dtype is np.int64 in this example
>>> c = np.ndarray((6,), dtype=np.int64, buffer=existing_shm.buf)
>>> c
array([ 4294967297, 12884901890, 34359738373,           0,           0,
                 0], dtype=int64)

这显然不是最初共享的数组。请注意,我只是直接从文档中复制粘贴示例,仅更改共享内存块的名称。有趣的是,即使在切换到第二个 Python shell 之前我没有创建数组“b”或将“a”复制到其中,也会发生同样的事情。

最后,在第二个 shell 中更改数组的最后一个元素可以正常工作:

>>> c[-1] = 888
>>> c
array([ 4294967297, 12884901890, 34359738373,           0,           0,
               888], dtype=int64)

但不影响第一个shell中的原始数组:

>>> # Back in the first Python interactive shell, b reflects this change
>>> b
array([1, 1, 2, 3, 5, 8])

有谁知道为什么会这样,或者我(连同官方文档)做错了什么?

谢谢!

【问题讨论】:

【参考方案1】:

在这里找到答案:https://bugs.python.org/issue39655

Windows 中 ndarray 的默认 dtype 是 int32,而不是 int64。更改后的示例有效。

(尽管此问题已作为错误提交并关闭,但开发人员很高兴不要在文档中提及这一点。)

【讨论】:

以上是关于(Python 多处理)如何访问与 multiprocessing.shared_memory.SharedMemory 共享的数组?的主要内容,如果未能解决你的问题,请参考以下文章

(Python 多处理)如何访问与 multiprocessing.shared_memory.SharedMemory 共享的数组?

如何隔离 Ruby 中的方法 - 多处理问题

如何在 Python 中的多处理期间访问全局变量 [重复]

在 gunicorn 工人之间共享一把锁

python面试题37道(附答案)看完面试不愁了

python 示例说明如何将实例方法与多处理模块一起使用