如何在Python多进程中创建共享的二维数组

1 投票
2 回答
2078 浏览
提问于 2025-06-18 04:11

我需要用Python的多进程来处理一个大矩阵。也就是说,我需要一个二维数组。这个数组应该可以被不同的子进程共享、访问和更新,并且要是同步的。因此我使用了mp.Manager

在创建数组时,multiprocess.Array()让我只能创建一个一维数组。我尝试用np.frombuffer()把这个“共享的一维数组”转换成一个二维的numpy数组(见CreateArray函数)。

在这个函数中,CreateArray(3,4)命令创建了一个长度为12的共享数组(=3x4)。但是,arr = np.frombuffer(mp_arr.get_obj())命令却只创建了一个长度为6的numpy数组!!!最后,b = arr.reshape((n, m))命令尝试把这个长度为6的数组转换成3x4的矩阵时失败了。

我该怎么解决这个问题,才能得到一个二维共享数组呢?

编辑:经过修正,代码创建了一个二维数组(感谢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)

enter image description here

相关问题:

  • 暂无相关问题
暂无标签

2 个回答

0

我觉得你应该传递共享内存的实例。现在你传递的是numpy数组,这个数组在通过多进程池时会被反序列化。你需要在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)
0

当你用numpy加载缓冲区时,应该使用方法frombufferdtype参数(默认是浮点数):

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

撰写回答