多进程向共享列表追加结果触发TypeError问题求助
解决多进程共享列表追加时的TypeError问题
你的问题根源出在Pool.map()的参数传递上,而非向共享列表追加的环节。让我拆解一下问题并给出解决方案:
错误原因
Pool.map(func, iterable[, chunksize])的定义里,第二个参数是单个可迭代对象,每个元素会作为func的唯一参数传入。但你写了p.map(process_file, wellfiles,L),这会让Python把L(ListProxy对象)当成了可选的chunksize参数——而chunksize要求是整数,所以它尝试比较ListProxy和整数,就抛出了TypeError: '<=' not supported between instances of 'ListProxy' and 'Int'。
正确的实现方式
要把共享列表L传递给每个子进程的process_file函数,有两种常用方法:
方法1:使用Pool.starmap()传递多参数
starmap支持传入包含多参数的元组列表,每个元组的元素会作为func的参数依次传入:
import lasio import glob from multiprocessing import Pool, Manager # 生成文件路径列表(简化写法) wellfiles = glob.glob("....filedirectory...//*") def process_file(filepath, L): las = lasio.read(filepath) uwi = las.well[11].value print(uwi) L.append(uwi) if __name__ == '__main__': with Manager() as manager: L = manager.list() # 把每个文件路径和共享列表打包成元组 tasks = [(file, L) for file in wellfiles] with Pool(5) as p: p.starmap(process_file, tasks) # 处理完后转成普通列表使用 result_list = list(L) print(result_list)
方法2:使用functools.partial绑定共享列表参数
把L预先绑定到process_file函数上,让每个子进程只需要接收文件路径参数:
import lasio import glob from multiprocessing import Pool, Manager from functools import partial wellfiles = glob.glob("....filedirectory...//*") # 注意调换参数顺序,让L作为第一个参数 def process_file(L, filepath): las = lasio.read(filepath) uwi = las.well[11].value print(uwi) L.append(uwi) if __name__ == '__main__': with Manager() as manager: L = manager.list() # 绑定L到process_file的第一个参数 bound_process = partial(process_file, L) with Pool(5) as p: p.map(bound_process, wellfiles) result_list = list(L) print(result_list)
额外优化建议
如果你的需求只是汇总结果,其实可以不用共享列表——直接让process_file返回uwi,然后用map的返回值收集结果,这样更简洁高效(避免共享对象的锁开销):
import lasio import glob from multiprocessing import Pool wellfiles = glob.glob("....filedirectory...//*") def process_file(filepath): las = lasio.read(filepath) uwi = las.well[11].value print(uwi) return uwi if __name__ == '__main__': with Pool(5) as p: result_list = p.map(process_file, wellfiles) print(result_list)
这种方式不需要Manager和共享列表,Pool.map()会自动把每个子进程的返回值收集成一个列表,代码更简洁,性能也更好。
内容的提问来源于stack exchange,提问作者Josiah Hulsey
相关产品推荐
相关产品推荐

