具体表现
把循环里定义的函数交给 Pool.map,进程池刚启动就抛 AttributeError 和 pickle 提示,子进程根本没跑起来。
先判断哪一层出错
进程间传参需要序列化,定义在函数内部的局部函数和闭包没有模块级名字,pickle 找不到对应对象。判断时先分清是 Python 多进程 pickle 本身的配置问题,还是上游调用、运行环境带进来的差异;前者改配置就能收口,后者要沿着请求链路一层层往上找,处理顺序不能颠倒。先在出问题的机器上复现一次,把报错原文和发生时间记下来,再对着日志定位。
操作步骤
- 把任务函数提到模块顶层
- 避免传 lambda 和类实例里的绑定方法
- 需要带参数时用 partial 或元组参数
对应的命令或配置片段如下,可直接复制:
from multiprocessing import Pool
def work(x):
return x * x
if __name__ == '__main__':
with Pool(4) as p:
print(p.map(work, range(10)))
测试环境复现不了时,先对比两边的版本号和配置文件,差异往往就在被忽略的那几行里。如果同一现象隔一段时间又出现,多半是某个定时任务或重启流程把配置覆盖回去了,顺手查一遍启动脚本。
收尾检查
进程池能正常返回结果列表,且没有序列化报错,说明函数已经可以被 pickle 识别。