【问题标题】:Sharing numpy arrays between multiple processes without inheritance在没有继承的情况下在多个进程之间共享 numpy 数组
【发布时间】:2016-04-21 19:59:16
【问题描述】:

我想在多个进程之间共享 numpy 数组。有工作解决方案here。但是它们都通过继承将数组传递给子进程,这对我不起作用,因为我必须事先启动一些工作进程,而且我不知道以后要处理多少个数组。有没有办法在进程启动后创建这样的数组,并通过队列将这些数组传递给进程?

顺便说一句,由于某种原因我无法使用multiprocessing.Manager

【问题讨论】:

  • 这里的“继承”是什么意思?
  • @Eric 创建进程时,它在内部执行fork 系统调用,并且父进程的所有程序状态都由子进程继承,包括共享内存句柄。避免传递继承的示例如下:stackoverflow.com/questions/9908781/…
  • 使用 pyzmq 交换数组既快速又灵活:github.com/zeromq/pyzmq/blob/master/examples/serialization/…
  • @Niemerds 谢谢!如果我使用 multiprocessing.Queue 发送数组,它会调用 pickle 转储,然后通过管道发送转储的字符串。使用 pyzmq 是否加快了这些步骤中的任何一步?
  • 肯定是的。 pickle 函数将数组数据转换为 (un-)pickle 操作使用的二进制格式,反之亦然,而 pyzmq 方法使用缓冲区接口发送/接收未修改的 numpy 数据。因此避免了双方不必要的数据复制或转换。

标签: python numpy multiprocessing shared-memory


【解决方案1】:

您应该使用shared memory,它完全可以解决您的用例。您保持内存读写速度,所有进程都可以在共享内存中的数组中读写,而不会产生任何序列化或传输成本。

以下是官方python文档中的示例:

>>> # 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  # We did not specify a name so one was chosen for us
'psm_21467_46075'
>>> # 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='psm_21467_46075')
>>> # 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([1, 1, 2, 3, 5, 8])
>>> c[-1] = 888
>>> c
array([  1,   1,   2,   3,   5, 888])
>>> # Back in the first Python interactive shell, b reflects this change
>>> b
array([  1,   1,   2,   3,   5, 888])
>>> # Clean up from within the second Python shell
>>> del c  # Unnecessary; merely emphasizing the array is no longer used
>>> existing_shm.close()
>>> # Clean up from within the first Python shell
>>> del b  # Unnecessary; merely emphasizing the array is no longer used
>>> shm.close()
>>> shm.unlink()  # Free and release the shared memory block at the very end

对于您的真实用例,您需要使用 Pipe 或任何其他多处理通信机制传递名称 shm.name。请注意,只有这个小字符串需要在进程之间交换;实际数据保留在共享内存空间中。

【讨论】:

    【解决方案2】:

    根据您的具体用例,将np.memmap 用于您要传输的阵列可能是一个不错的方法。数据将在磁盘上,但它像标准数组一样使用,并且只有“标题”数据在队列中被腌制,所以它非常快。

    https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

    【讨论】:

      猜你喜欢
      • 2016-09-29
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      • 2013-07-21
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      相关资源
      最近更新 更多