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

为什么Python multiprocessing在大数据量下无法正常并行运行?

问题原因

  • 进程间参数传递的串行开销:multiprocessing.Process给子进程传参数时,会先将参数通过pickle序列化后写入IPC管道,该操作由主进程串行执行。小数据量时序列化+传输耗时极短,4个进程几乎同时收到输入启动计算,表现为并行;大数据量时单组输入序列化传输就要花较长时间,主进程要依次写完4组数据才能完成所有子进程的启动准备,导致子进程逐个启动执行,看起来退化成了串行/并发。
  • 写时复制机制失效:Linux下multiprocessing默认使用fork模式创建子进程,原本子进程可以直接共享父进程的内存数据,只有修改时才会复制。但你的代码中直接把大列表作为参数传给子进程,触发了主动序列化传输,没有利用写时复制的优势,额外增加了数据传输开销。
  • 系统资源瓶颈:如果单组1e6规模的数据排序/shuffle已经占满了单核心CPU,或者内存带宽不足,多个进程同时运行时会出现资源争抢,也会导致整体执行表现和串行接近,看起来像退化成了并发。

修复方案

  • 避免直接传大对象作为进程参数,利用写时复制减少传输开销:把输入的lists变量放在主进程的全局作用域,子进程fork之后直接读取对应下标的数据,不需要通过参数传递,避免序列化开销。修改后参考代码如下:
import multiprocessing

# 输入数据放在主进程全局作用域,子进程fork后可直接共享读取
lists = [...] # 你的4组输入数据

def subList_process(idx):
    print("start")
    instance = lists[idx]
    l = List(dataSet=instance)
    l.shuffle_set()
    l.sort_set()
    print("done")

if __name__ == '__main__': 
    p=[]
    # 仅传递下标作为参数,序列化传输几乎无开销
    for i in range(4):
        p.append(multiprocessing.Process(target=subList_process,args=(i,)))
    
    for process in p : process.start()
    for process in p : process.join()
  • 使用共享内存容器存储大输入:如果是Windows系统(默认使用spawn模式创建子进程,不支持fork的写时复制),可以用multiprocessing.Array、multiprocessing.Manager列表,或者Python 3.8+的multiprocessing.shared_memory模块存储输入数据,子进程直接访问共享内存,不需要全量复制传输数据。
  • 显式指定进程启动模式:Linux下可以在主入口第一行添加multiprocessing.set_start_method('fork'),确保写时复制机制生效;Windows下使用spawn模式时要尽量压缩传参大小,仅传递必要的元数据即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:24:05