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

Python3.7使用multiprocessing与pickle时触发无法pickle本地对象错误

错误原因

你遇到的Can't pickle local object报错是Python标准库multiprocessing的序列化机制限制:

  • 模块默认用pickle做跨进程参数/函数的序列化,pickle不支持序列化定义在函数/方法内部的局部嵌套函数、lambda表达式这类非顶层作用域的对象
  • 你的代码里还有一个基础写法错误:创建Process时你在target参数位置直接调用了目标函数,相当于在主进程同步执行函数后,把函数返回值当成了进程入口,完全不符合多进程的传参规则,也会触发序列化异常。
    另外你贴的复现代码里din/dout_list/proc_list几个变量没有初始化,且多进程逻辑没有放在主入口判断块内,在Windows/macOS环境下还会触发子进程递归启动的问题。
修复步骤
  1. 修正进程target传参逻辑:target参数只传函数对象本身,函数调用需要的参数全部放到args元组里传入,也就是你注释掉的那行写法才是正确的:
    # 错误写法:直接调用函数,返回值作为target
    # process = multiprocessing.Process(target=Run_IDEAS_instance_get_trajectory(din_temp, dout_list[-1]))
    # 正确写法:传函数对象+参数元组
    process = multiprocessing.Process(target=Run_IDEAS_instance_get_trajectory,args=(din_temp, dout_list[-1]))
    
  2. 把进程入口函数挪到模块顶层:不要把Run_IDEAS_instance_get_trajectory定义在其他函数内部,确保它是模块全局可直接导入的顶层对象,满足pickle的序列化要求。
  3. 补全主入口判断:所有多进程启动、Manager初始化的逻辑必须放在if __name__ == "__main__":块内,避免spawn启动模式下的递归启动问题。
  4. 如果你确实需要用局部嵌套函数、lambda这类无法被pickle序列化的对象,可以换用pathos.multiprocessing替代标准库的multiprocessing,它用dill做序列化后端,支持大部分局部对象的序列化,不过这个方案需要额外安装依赖,优先用前三个方案兼容性最好。
修复后可运行参考代码
import multiprocessing
import copy
from pathlib import Path

# 进程入口函数必须定义在模块顶层
def Run_IDEAS_instance_get_trajectory(input_config, output_dict):
    # 替换成你自己的业务逻辑
    output_dict['status'] = 'success'
    output_dict['config_recv'] = input_config

if __name__ == "__main__":
    # Manager、队列、进程列表这类对象全部放在主入口内初始化
    proc_mrg = multiprocessing.Manager()
    num_cpu = 8
    din = {}
    dout_list = []
    proc_list = []

    def prepare_run(config):
        din['config'] = config
        din_temp = copy.deepcopy(din)
        dout_list.append(proc_mrg.dict({}))
        process = multiprocessing.Process(
            target=Run_IDEAS_instance_get_trajectory,
            args=(din_temp, dout_list[-1])
        )
        proc_list.append(process)

    # 测试调用
    prepare_run({"test_key": "test_value"})
    for job in proc_list:
        job.start()
    for job in proc_list:
        job.join()  # 等待所有进程执行完成
    
    # 打印执行结果
    for res in dout_list:
        print(dict(res))
额外注意
  • 不要在子进程里依赖主进程的全局变量状态,多进程内存是隔离的,跨进程传值必须通过args显式传参,或者用Manager创建的共享对象。
  • 如果进程入口是类实例方法,要确保对应的类也是顶层定义,且类实例本身可被pickle序列化,否则同样会触发同类报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:03:24