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

如何为列表中每个对象生成新进程,替代串行执行以提速?

用Python多进程优化串行遍历的耗时问题

嗨,针对你这个串行处理80个对象耗时7小时的问题,换成多进程并行处理绝对是最优解之一!下面我给你具体的实现方案、示例代码,以及一些实操中的注意事项,帮你把运行时间大幅压缩。

推荐工具:Python标准库multiprocessing

Python的multiprocessing模块是专门用来实现多进程并行的,相比subprocess(更适合调用外部程序),它更适合Python内部函数的并行执行,轻量且进程间通信更方便。而且它能绕过GIL(全局解释器锁)的限制,真正利用多核CPU的性能,完美解决你的串行耗时问题。

两种常用的多进程实现方式

方式1:进程池(Pool)—— 最简洁的批量处理方案

进程池会帮你管理进程的创建、复用和销毁,不用手动维护每个进程,非常适合处理批量对象的场景。

示例代码

假设你原来的串行代码是这样的:

listName = [obj1, obj2, ..., obj80]
i = 0
while i < len(listName):
    print(f"blah {i}")
    # 这里是你对每个对象的多项操作,比如:
    # listName[i].task1()
    # listName[i].task2()
    i += 1

改成进程池版本:

import multiprocessing

# 把每个对象的操作封装成单独的函数
def process_single_object(obj, index):
    print(f"blah {index}")
    # 这里放你原来的多项操作逻辑
    obj.task1()
    obj.task2()
    # 如果有返回结果,直接return即可,进程池会收集结果

if __name__ == "__main__":
    listName = [obj1, obj2, ..., obj80]
    
    # 获取CPU核心数(也可以手动指定,比如8,不用超过核心数太多)
    worker_count = multiprocessing.cpu_count()
    
    # 创建进程池并执行任务
    with multiprocessing.Pool(worker_count) as pool:
        # 用starmap传递多个参数(对象和索引)
        results = pool.starmap(
            process_single_object,
            [(obj, idx) for idx, obj in enumerate(listName)]
        )
    
    # 如果有返回结果,results就是所有进程的返回值列表
    # print(results)

方式2:手动创建Process对象—— 更精细的进程控制

如果你需要对每个进程的启动、关闭、资源分配做更精细的控制,可以手动创建Process对象:

import multiprocessing

def process_single_object(obj, index):
    print(f"blah {index}")
    # 你的业务操作逻辑

if __name__ == "__main__":
    listName = [obj1, obj2, ..., obj80]
    processes = []
    
    # 逐个创建并启动进程
    for idx, obj in enumerate(listName):
        p = multiprocessing.Process(
            target=process_single_object,
            args=(obj, idx)
        )
        processes.append(p)
        p.start()
    
    # 等待所有进程执行完成
    for p in processes:
        p.join()

实操中的关键注意事项

  1. 必须加if __name__ == "__main__":Windows系统下多进程需要这个判断来避免重复启动子进程,跨平台开发时一定要加上,否则会报错。
  2. 对象可序列化:传递给子进程的对象必须是可pickle序列化的,如果你的自定义对象不能被序列化,建议传递对象的关键参数(比如ID、路径),在子进程里重新初始化对象。
  3. 进程数不要贪多:进程数设置为CPU核心数的1-2倍即可,太多会导致进程切换开销剧增,反而变慢。比如8核CPU,设8-12个进程就好。
  4. 日志与输出:多进程下print的内容会乱序,建议用logging模块替代,给每个日志加上进程ID或对象索引,方便排查问题。
  5. 错误处理:如果某个对象处理失败,最好在process_single_object里用try-except捕获异常,或者用进程池的error_callback回调处理错误:
    def handle_error(exc):
        print(f"处理对象时出错:{exc}")
    
    with multiprocessing.Pool(worker_count) as pool:
        for idx, obj in enumerate(listName):
            pool.apply_async(
                process_single_object,
                args=(obj, idx),
                error_callback=handle_error
            )
        pool.close()
        pool.join()
    
  6. 关于subprocess:如果你每个对象的操作是调用外部脚本/命令,subprocess也可以用,但需要手动管理子进程的启动和等待,复杂度比multiprocessing高。如果是Python内部逻辑,优先用multiprocessing。

效果预期

如果你的任务是CPU密集型,用8核CPU的话,理论上能把7小时的耗时压缩到1小时左右(实际取决于任务的并行度);如果是IO密集型(比如等待网络、文件读写),提升效果会更明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:09:52