You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python多进程无法修改二维数组行?如何解决?

问题原因

你用mp.Manager().list()创建的外层列表是进程共享对象,但里面的子列表a[0]、a[1]是普通Python列表,不属于进程共享范畴。当你把这些子列表传给子进程时,它们会被pickle序列化后复制到子进程的独立内存空间——子进程修改的只是自己手里的副本,完全碰不到主进程里的原列表元素,所以主进程最后打印的还是初始值。


解决方案1:嵌套使用Manager共享列表

把每个子列表也改成mp.Manager().list()类型,让所有层级的列表都是进程共享对象,子进程的修改会同步回主进程:

import multiprocessing as mp

def incr(a):
    for i in range(len(a)):
        a[i] += 1

if __name__ == "__main__":
    manager = mp.Manager()
    # 外层和内层都用Manager创建共享列表
    a = manager.list([
        manager.list([0, 1, 2]),
        manager.list([3, 4, 5])
    ])
    
    with mp.Pool(2) as pool:
        pool.map(incr, [a[0], a[1]])

    print(a)  # 输出: [[1, 2, 3], [4, 5, 6]]

解决方案2:子进程返回结果,主进程更新

不依赖共享对象,让子进程处理完子列表后返回新结果,主进程再替换原数组的对应行:

import multiprocessing as mp

def incr(a):
    # 返回修改后的新列表
    return [x + 1 for x in a]

if __name__ == "__main__":
    a = [[0, 1, 2], [3, 4, 5]]
    
    with mp.Pool(2) as pool:
        # 接收子进程返回的所有修改后行
        updated_rows = pool.map(incr, a)
    
    a = updated_rows
    print(a)  # 输出: [[1, 2, 3], [4, 5, 6]]

这种方式逻辑简单,避免了共享对象的同步开销,适合大多数场景。


解决方案3:使用共享内存数组(适合数值型数据)

如果你的数组是纯数值类型(整数、浮点数等),可以用mp.Array创建基于共享内存的数组,配合numpy操作更高效:

import multiprocessing as mp
import numpy as np

def incr(arr, row_idx):
    # 将共享内存数组转为numpy数组切片
    np_arr = np.frombuffer(arr.get_obj(), dtype=np.int32).reshape(2, 3)
    np_arr[row_idx] += 1

if __name__ == "__main__":
    # 创建共享内存数组,指定类型为int32,长度6(对应2行3列)
    shared_arr = mp.Array('i', [0,1,2,3,4,5])
    # 转为numpy数组方便操作
    a = np.frombuffer(shared_arr.get_obj(), dtype=np.int32).reshape(2,3)
    
    with mp.Pool(2) as pool:
        # 给每个进程传共享数组和要处理的行索引
        pool.starmap(incr, [(shared_arr, 0), (shared_arr, 1)])

    print(a)  # 输出: [[1 2 3]
              #        [4 5 6]]

这种方式性能最优,直接操作共享内存,没有序列化复制的开销,但仅适合数值类型,需要处理数组形状转换。

内容的提问来源于stack exchange,提问作者Paul Jurczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:15:09