【问题标题】:Check if Numpy Array is Stored in Shared Memory检查 Numpy 数组是否存储在共享内存中
【发布时间】:2020-12-23 01:10:37
【问题描述】:

在 Python 3.8+ 中,是否可以检查 numpy 数组是否存储在共享内存中?

在以下示例中,使用 multiprocessing.shared_memory.SharedMemory 对象的缓冲区创建了一个 numpy 数组 sharedArr。想知道能不能写个函数检测SharedMemory是否被使用。

import numpy as np
from multiprocessing import shared_memory

if __name__ == '__main__':
    # Created numpy array `sharedArr`in shared memory
    arr = np.zeros(5)
    shm = shared_memory.SharedMemory(create=True, size=arr.nbytes)
    sharedArr = np.ndarray(arr.shape, dtype=arr.dtype, buffer=shm.buf)
    sharedArr[:] = arr[:]

    # How to tell if numpy array is stored in shared memory?
    print(type(sharedArr))      # <class 'numpy.ndarray'>
    print(hex(id(sharedArr)))   # 0x7fac99469f30

    shm.close()
    shm.unlink()

【问题讨论】:

  • hex(id(...)) 是一个巨大的红鲱鱼。这不是一个有用的方法来确定底层缓冲区发生了什么。 id 不 提供内存地址,这是一个 CPython 实现细节,它只是一个在对象的生命周期内保证唯一的数字。在这种情况下,它是 np.ndarray 对象的 PyObject 标头的地址,但这与缓冲区无关,实际上,您可以创建任意数量的 numpy.ndarray 具有不同 id 的对象共享同一个缓冲区

标签: python python-3.x numpy shared-memory sysv


【解决方案1】:

在这种特殊情况下,您可以使用共享数组的base 属性。 attribute 是对该数组从中派生其内存的底层对象的引用。对于大多数数组,这是None,表示这样的数组拥有它的数据。在我的机器上运行这段代码表明这个数组的基是一个mmap 对象:

>>> sharedArr.base
<mmap.mmap at 0x11a4aa670>

如果您仍然有对分配数组的共享内存对象的引用,您可以将数组的基址与共享内存段的内存映射进行比较:

>>> sharedArr.base is shm._mmap
True

如果您没有周围有 shm 对象,因为您不会使用可以假设执行此任务的独立函数,我怀疑是否有一种可移植且万无一失的方法它。

由于 NumPy 提供了自己的 memory-map object,因此您的案例进行前一项检查就足够了。也就是说,假设如果数组由普通的内置 Python 内存映射支持,则它是从共享内存分配的:

import mmap

def array_is_from_shared_memory(arr):
    return isinstance(arr.base, mmap.mmap)

这在您的特定示例中有效,但您必须小心,清楚记录它所做的假设,并测试它是否为您提供了您需要的实际信息确切的应用。

【讨论】:

  • 惊人的答案,谢谢!有哪些对象不受 mmap 支持但仍保存在共享内存中的示例?
  • 很高兴您发现这个答案很有帮助!可能出现的问题完全取决于您对这些数组所做的工作。如果该假设不成立,则有两种情况。考虑一个由共享内存支持的数组不在后台使用mmap。然后这个函数会导致你在你想在共享数组上运行的任何代码中“错过”这个数组。 OTOH,确实使用mmap但未实际共享的数组可能会导致您无意中覆盖某些数据,或者期望更改会显示在其他地方,即使它不会。这些有多“糟糕”取决于您的用例:)
猜你喜欢
  • 2021-03-14
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 2015-06-20
相关资源
最近更新 更多