使用tqdm的process_map时如何在多进程间共享列表进行追加操作?
问题根因
你的代码失效的核心原因是多进程的全局变量隔离机制:Windows/macOS平台默认使用spawn模式启动子进程,子进程会重新导入整个脚本文件,且不会执行if __name__ == '__main__'包裹的代码段。因此子进程中访问的shared_list是代码顶部定义的普通空列表,和主进程中创建的Manager共享列表属于完全独立的两个对象,子进程的append操作不会同步到主进程的共享列表中。
解决方法
方案1(更推荐):直接使用process_map返回值
process_map本身就会收集所有worker函数的返回值,按输入顺序组合成列表返回,不需要额外维护共享变量,既简洁也没有并发读写风险:
import time from tqdm.contrib.concurrent import process_map def worker(i): time.sleep(1) # 直接返回需要收集的结果 return i if __name__ == '__main__': # process_map的返回值就是所有worker的输出集合 result_list = process_map(worker, range(20), max_workers=5) print(result_list)
方案2:确实需要共享列表时,显式传参给worker
如果你的场景必须使用共享容器(比如运行中需要跨进程读写状态),不要用全局变量传递共享对象,用functools.partial把共享列表绑定为worker的入参:
import time from functools import partial from tqdm.contrib.concurrent import process_map from multiprocessing import Manager def worker(shared_list, i): time.sleep(1) shared_list.append(i) if __name__ == '__main__': manager = Manager() shared_list = manager.list() # 用partial绑定共享列表参数 bound_worker = partial(worker, shared_list) process_map(bound_worker, range(20), max_workers=5) print(shared_list)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

