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

使用Pool对象并行反序列化多个pickle文件为何卡顿?

问题原因

在Windows系统中,multiprocessing默认使用spawn方式启动子进程,这种方式会重新导入主模块。如果代码未用if __name__ == '__main__':包裹主程序逻辑,子进程启动时会重复执行创建Pool的代码,导致无限递归创建子进程,最终CPU利用率拉满,进程挂起无法终止。Spyder的交互式环境会放大这个问题,因为子进程的启动逻辑会被反复触发。

修复方案

把所有需要在主进程执行的逻辑(包括创建pickle文件、并行加载的代码)都放到if __name__ == '__main__':代码块中,避免子进程重复执行这些逻辑。

整合版代码(创建+加载)

import pickle
from multiprocessing import Pool

class A:
    x: int
    y: str
    
    def __init__(self, x:int, y:str):
        self.x = x
        self.y = y

if __name__ == '__main__':
    # 创建pickle文件
    for i in range(6):
        with open(str(i) + '.pkl', 'wb') as f:
            pickle.dump(A(i, str(i) + 'abcdefg'), f)
    
    # 并行加载函数
    def load(file):
        with open(file, 'rb') as f:
            data = pickle.load(f)
        return data  # 可选:返回数据方便后续处理
    
    # 并行加载
    with Pool(4) as p:  # 建议设置为物理核心数,避免进程切换开销
        results = p.map(load, [str(number) + '.pkl' for number in range(6)])

拆分版代码

如果创建文件和加载需要分开执行,可拆分为两个脚本:

创建pickle文件的脚本

import pickle

class A:
    x: int
    y: str
    
    def __init__(self, x:int, y:str):
        self.x = x
        self.y = y

if __name__ == '__main__':
    for i in range(6):
        with open(str(i) + '.pkl', 'wb') as f:
            pickle.dump(A(i, str(i) + 'abcdefg'), f)

并行加载的脚本

import pickle
from multiprocessing import Pool

class A:
    x: int
    y: str
    
    def __init__(self, x:int, y:str):
        self.x = x
        self.y = y

def load(file):
    with open(file, 'rb') as f:
        data = pickle.load(f)
    return data

if __name__ == '__main__':
    with Pool(4) as p:
        results = p.map(load, [str(number) + '.pkl' for number in range(6)])
补充说明
  • 类A的定义可放在模块顶级,子进程需要导入该类才能正确反序列化pickle对象,这部分是安全的。
  • 进程池数量建议设置为物理核心数(比如你的4个物理核心),过多进程会增加切换开销,反而降低效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:50:28