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

Python 3.6并行加载多文件至内存的最优方法及问题解决

搞定多进程并行加载pickle文件的问题

嘿,你的代码里藏着一个关键小错误,这就是为什么多进程没生效、程序还是串行跑的原因!

你看,调用pool.apply_async(load1(),)的时候,加了括号的load1()会立刻执行这个函数,等它加载完文件、返回结果后,才把结果传给apply_async——相当于三个加载函数还是一个接一个跑完的,进程池根本没发挥并行的作用!

修正后的代码示例

先把函数调用改成传递函数对象(去掉括号),如果你的加载函数需要参数(比如文件名),把参数放在apply_async的args参数里就行。这里给你调整后的完整代码:

import timeit
from multiprocessing import Pool
import pickle

# 写通用的加载函数,不用重复写load1/load2/load3
def load_pickle(file_path):
    with open(file_path, 'rb') as f:
        return pickle.load(f)

def loadMaps():
    start = timeit.default_timer()
    # 6个文件的话,把这里的路径改成你的6个文件路径
    file_paths = ['file1.pkl', 'file2.pkl', 'file3.pkl']
    
    # 创建进程池,进程数设为文件数(你排除了IO限制,这样能最大化并行)
    with Pool(processes=len(file_paths)) as pool:
        # 提交所有加载任务,注意是传函数对象+参数,不是直接调用函数
        tasks = [pool.apply_async(load_pickle, args=(path,)) for path in file_paths]
        
        # 如果需要获取加载后的字典,用get()方法逐个取出
        loaded_dicts = [task.get() for task in tasks]
    
    stop = timeit.default_timer()
    print('loadFiles takes in %.1f seconds' % (stop - start))

# Windows系统必须加这个判断!否则多进程会出奇怪的错误
if __name__ == '__main__':
    loadMaps()

几个重要的小提示

  • 为什么用with语句管理Pool? 这样不用手动写pool.close()和pool.join(),with块结束后会自动处理,代码更简洁安全。
  • 进程数怎么设? 你已经排除了IO限制,那进程数设为文件数(6个)就好,这样每个文件对应一个进程,刚好并行加载。
  • Windows用户必看:Windows的多进程是spawn模式,必须把主执行逻辑放在if __name__ == '__main__':下面,否则会重复创建进程,导致程序崩溃或者不工作。
  • 代码复用性:用通用的load_pickle函数代替多个load1/load2,后续加更多文件只需要修改file_paths列表就行,维护起来方便多了。

按照这个代码改完,应该就能真正实现并行加载,把时间压到100秒左右啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:38:22