Python多进程:map/starmap与apply_async该选哪个?如何处理结果?
问题解答
1. starmap vs map:选哪个更适配你的场景?
你的函数movingWinStretch需要接收两个独立的一维数组参数u0、u1,这种多输入场景下:
map只能处理单参数迭代器,每个元素对应函数的单个输入,完全不匹配你的双参数需求。starmap可以直接接收由多参数元组组成的迭代器,会自动把元组里的元素拆包成函数的多个参数,完美适配你的traceIterator(假设它生成的是(u0, u1)格式的元组)。
结论:优先用starmap,代码结构更简洁,不需要额外的参数包装操作。
2. 用starmap批量收集多返回值
因为函数返回C、epsArray、tSamp三个结果,你可以先一次性收集所有返回的三元组,再拆分到对应列表中:
from multiprocessing import Pool def movingWinStretch(u0, u1): # 你的函数逻辑,最终返回C, epsArray, tSamp ... if __name__ == "__main__": # 假设traceIterator生成(u0, u1)格式的元组迭代器 with Pool() as pool: # 批量执行任务,得到所有三元组结果的列表 all_results = pool.starmap(movingWinStretch, traceIterator) # 拆分结果到对应列表 C_list = [] epsArray_list = [] tSamp_list = [] for res in all_results: C_list.append(res[0]) epsArray_list.append(res[1]) tSamp_list.append(res[2])
3. 若坚持用apply_async,怎么分别收集结果?
apply_async需要通过回调函数处理每个任务的返回值,你可以定义一个回调函数同时处理三个结果,直接追加到对应列表:
from multiprocessing import Pool def movingWinStretch(u0, u1): ... if __name__ == "__main__": C_list = [] epsArray_list = [] tSamp_list = [] # 定义回调函数,处理单个任务的返回值 def collect_single_result(result): c, eps, ts = result C_list.append(c) epsArray_list.append(eps) tSamp_list.append(ts) with Pool() as pool: # 遍历迭代器,逐个提交任务 for u0, u1 in traceIterator: pool.apply_async(movingWinStretch, args=(u0, u1), callback=collect_single_result) # 等待所有任务执行完毕 pool.close() pool.join()
注意:回调函数是在主进程中执行的,所以不需要担心列表的多进程同步问题——主进程是唯一操作这些列表的进程。
4. 性能与实用性对比
starmap是批量提交任务,内部调度更高效,代码简洁易维护,完全匹配你的需求,是首选方案。apply_async是逐个提交任务,灵活性更高(比如给不同任务设置不同回调),但代码相对繁琐,性能略逊于批量提交的starmap。
内容的提问来源于stack exchange,提问作者magmadaddy
相关产品推荐
相关产品推荐

