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

如何使用multiprocessing.Pool().map修改共享对象A?

解决Python多进程中无法修改共享对象的问题

这个问题我之前帮不少开发者捋清楚过——本质是多进程的内存隔离特性在搞鬼!当你用multiprocessing.Pool创建子进程时,每个子进程都会复制一份父进程的内存空间,你在子进程里修改的A只是它自己副本里的那个,根本不会同步回父进程的原始A,这就是为什么并行执行后父进程的A还是初始值。

下面给你两种实用的解决方案,分别适配不同的场景:

方法一:用multiprocessing.Array(适合固定大小的基础类型数组)

Array是多进程安全的共享内存对象,能直接在父子进程间共享数据,适合像你这种固定长度的整数列表场景。

修改后的代码如下:

import multiprocessing

def square(i, shared_A):
    shared_A[i] = 2 + shared_A[i]
    return i * i

if __name__ == "__main__":
    # 创建共享数组,指定类型为整数('i'),初始值[1,2]
    A = multiprocessing.Array('i', [1, 2])
    # 串行执行测试
    square(0, A)
    square(1, A)
    print(list(A))  # 输出 [3, 4]
    
    # 重置共享数组
    A[:] = [1, 2]
    # 并行执行
    with multiprocessing.Pool() as pool:
        # 用starmap传递多个参数给square函数
        pool.starmap(square, [(0, A), (1, A)])
    print(list(A))  # 输出 [3, 4]

方法二:用multiprocessing.Manager(适合灵活的列表/字典等复杂结构)

如果你的共享对象需要更灵活的操作(比如动态增删元素),那Manager就更合适了——它会启动一个专门的管理进程来维护共享对象,子进程通过代理访问,支持各种Python标准数据结构。

代码示例:

import multiprocessing

def square(i, shared_A):
    shared_A[i] = 2 + shared_A[i]
    return i * i

if __name__ == "__main__":
    with multiprocessing.Manager() as manager:
        # 创建共享列表
        A = manager.list([1, 2])
        # 串行测试
        square(0, A)
        square(1, A)
        print(list(A))  # 输出 [3, 4]
        
        # 重置共享列表
        A[:] = [1, 2]
        # 并行执行
        with multiprocessing.Pool() as pool:
            pool.starmap(square, [(0, A), (1, A)])
        print(list(A))  # 输出 [3, 4]

几个关键注意点:

  • 别再用全局变量传共享对象了!必须把共享对象作为参数显式传递给子进程函数,不然子进程只会操作自己的副本。
  • Array的性能比Manager好一些,因为它直接用共享内存,而Manager需要进程间通信同步数据,性能敏感的场景优先选Array。
  • Windows系统下一定要把多进程代码放在if __name__ == "__main__":块里,不然会触发重复创建进程的bug,踩过坑的人都懂😅

内容的提问来源于stack exchange,提问作者J. Lin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:52:13