如何在 python 多处理中创建共享二维数组

How to create a shared 2D array in python multiprocessing

我需要使用 python 的多处理来处理一个大矩阵。那就是说我需要 一个二维数组 。该数组应该由不同的子进程以同步方式shared/accessed/updated。 (因此我使用mp.Manager)。

关于创建数组,multiprocess.Array() 让我创建一个一维数组。我尝试使用 np.frombuffer() 将 "Shared 1D array" 转换为二维 numpy 数组(参见 CreateArray 函数)。

在函数中,CreateArray(3,4) 命令创建一个长度为 12 (=3x4) 的共享数组。但是 arr = np.frombuffer(mp_arr.get_obj()) 命令创建了一个长度为 6 的 numpy 数组!!!。最终 b = arr.reshape((n, m)) 命令无法将大小为 6 的数组转换为 3x4 矩阵。

如何解决此问题并获得 2D 共享 数组?

编辑: 通过更正,代码折痕了一个二维数组(感谢 GabrielC)。但看起来数组没有共享。函数 addData(array) 在矩阵中分配一些值。但是当从 main 打印时,我只得到零。

问题:如何解决这个问题并得到一个二维共享数组?

import multiprocessing as mp
import numpy as np
import ctypes as c

def CreateArray(n,m):
    mp_arr=mp.Array('i',n*m)
#    arr = np.frombuffer(mp_arr.get_obj())  #This command must be corrected. Thanks to GabrielC
    arr = np.frombuffer(mp_arr.get_obj(),c.c_int)  # mp_arr and arr share the same memory
    # make it two-dimensional
    print('np array len=',len(arr))
    b = arr.reshape((n, m))  # b and arr share the same memory
    return b

def addData(array):
    n,m=np.shape(array)
    i=0
    for nn in range(n):
        for mm in range(m):
            array[nn][mm]=i
            i=i+1
    print(array)

if __name__=='__main__':
    with mp.Manager() as manager:
        Myarray=CreateArray(3,4)
        p1=mp.Process(target=addData,args=(Myarray,))
        p1.start()
        p1.join()
        print(Myarray)

当你用numpy加载缓冲区时,你应该使用frombuffer方法的dtype参数(默认是float):

arr = np.frombuffer(mp_arr.get_obj(), c.c_int)

我相信你应该传递共享内存的实例。您当前正在传递 numpy 数组,它在通过多处理池时将 de-serialized。您将不得不在 addData 函数中重塑数组,但这只是为数组提供一个新视图,应该很快。

import multiprocessing as mp
import numpy as np
import ctypes as c

def CreateArray(n,m):
    return mp.Array('i',n*m)

def addData(mp_arr):

    arr = np.frombuffer(mp_arr.get_obj(),c.c_int)
    arr = arr.reshape((n, m))

    i=0
    for nn in range(n):
        for mm in range(m):
            arr[nn][mm]=i
            i=i+1
    print(arr)

if __name__=='__main__':
    with mp.Manager() as manager:
        Myarray=CreateArray(3,4)
        p1=mp.Process(target=addData,args=(Myarray,))
        p1.start()
        p1.join()
        print(Myarray)