python - 为什么Python共享内存需要副本?

标签 python numpy shared-memory

我试图构建一个新 Python 的简单示例 SharedMemory通过修改共享 numpy 数组来创建类。我在网上看到了一些例子:

Shared memory in multiprocessing

Is shared readonly data copied to different processes for multiprocessing?

但是它们都更改了 __main__ 内的共享数组由于某种原因阻塞,然后打印它。但是,我想从函数中返回一个共享数组并稍后重用它。这是我的尝试:

from multiprocessing import shared_memory
import numpy as np


def create_shared_array():
    # instantiate array
    np_array = np.ones((5, 2, 2))
    # instantiate shared array
    shm = shared_memory.SharedMemory(size=np_array.nbytes, create=True)
    # copy data from original array into shared array
    array_shared = np.ndarray(np_array.shape, dtype=np_array.dtype, buffer=shm.buf)
    array_shared[:] = np_array[:]
    return shm


def change_and_return(name):
    existing_shm = shared_memory.SharedMemory(name=name, create=False)
    array_shared = np.ndarray((5, 2, 2), dtype=np.float64, buffer=existing_shm.buf)
    # change shared array
    array_shared[0] = 888
    return array_shared


shm = create_shared_array()
result = change_and_return(shm.name)
print(result)

出于某种原因,此代码返回 "The instruction at <memory address> referenced memory at <another address>. The memory could not be read."在我的 Windows 机器上。

但是,如果我只是替换它

return array_shared

有了这个

return array_shared.copy()

然后就可以正常工作了。

我的想法:

change_and_return不返回existing_shm然后它被垃圾收集并 array_shared也被摧毁了。不过,我确实确保不杀死shm所以引用应该仍然存在?

问题:为什么需要额外的副本以及避免制作额外副本的正确方法是什么?

更新:让我在这里说清楚 - 我想更改共享内存中的数组值,但之后我想以非共享方式使用它。就像常规的 numpy 数组一样。所以问题基本上是是否可以在不复制的情况下将共享数组转回非共享数组?

最佳答案

文案错误。它创建了一个由非共享内存支持的数组,完全违背了您正在做的事情的意义。

你说的是

However, I do make sure not to kill shm

但事实并非如此。您无需采取任何措施来保持 shm 的存活。它死了,它的__del__ method调用close,并且内存不再可访问。

您需要保留对shm的引用以确保内存仍然可以访问。此外,为了正确清理,每个进程都应在不再需要使用共享内存后调用 shm.close(),并且单个进程应调用 shm.unlink() > 在所有进程调用close之后。否则,即使程序终止也会面临内存泄漏的风险。 (在 Unix 上,Python 生成 server process 来尝试防止这种情况,但它并不完全可靠,即使它有效,它也会在晚些时候执行清理。)

关于python - 为什么Python共享内存需要副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66003184/

相关文章:

python - 在python中使用gurobi属性进行近似优化

python - Jupyter Notebook 打开一个空浏览器

python - 使用 numpy 同时对角化矩阵

Python将简历图像存储在mongodb gridfs中

python - NumPy 中 random_integers 的替代方案

Python Multiprocessing 共享全局值

c++ - CreateFileMapping/MapViewOfFile 返回的共享内存数组是否初始化为零?

python - 当 QProgressBar 存在时,如何居中对齐 QPushButton?

python - 如何在pytorch中测试一张图片

c - 在Linux中使用共享内存时如何修复 "Segmentation fault (core dumped)"