如何在Python multiprocessing中中断Pool.map且不丢失已计算结果
解决multiprocessing Pool.map()中断时保留已完成结果的问题
原代码的核心问题是Pool.map()会阻塞至所有任务完成后才返回完整结果集,一旦触发KeyboardInterrupt,output变量还未被赋值,自然无法获取任何已完成的计算结果。要实现中断时保留已完成结果、跳过待处理任务的需求,可改用Pool.imap()或Pool.imap_unordered()来迭代获取结果,具体方案如下:
方案1:按输入顺序保留结果(imap)
imap()会按照任务的输入顺序返回已完成的结果,适合需要保持结果顺序的场景:
from multiprocessing import Pool from time import sleep def f(i): sleep(i) return i if __name__ == "__main__": # 提前初始化结果列表,避免中断时变量未定义 completed_results = [] with Pool() as p: try: # 迭代获取每个已完成任务的结果 for res in p.imap(f, range(10)): completed_results.append(res) except KeyboardInterrupt: # 立即终止所有子进程,停止处理待任务 p.terminate() finally: # 等待池内进程清理完成 p.join() print("已完成的结果(按输入顺序):", completed_results)
方案2:优先返回完成的结果(imap_unordered)
如果不需要结果和输入顺序一致,imap_unordered()会优先返回先完成的任务结果,效率更高:
from multiprocessing import Pool from time import sleep def f(i): sleep(i) return i if __name__ == "__main__": completed_results = [] with Pool() as p: try: # 不保证顺序,谁先完成谁先返回 for res in p.imap_unordered(f, range(10)): completed_results.append(res) except KeyboardInterrupt: p.terminate() finally: p.join() print("已完成的结果(无顺序):", completed_results)
关键说明
- 提前初始化结果列表:确保即使触发中断,也能保留已经收集到的结果。
terminate()vsclose():terminate()会强制终止所有子进程,正在运行的任务直接终止;若希望正在运行的任务完成后再停止,可替换为p.close()(禁止提交新任务),再在finally中执行p.join()等待剩余任务完成。- 必须包裹在
if __name__ == "__main__":下:Windows系统中multiprocessing模块的强制要求,避免子进程重复执行主模块代码。
内容的提问来源于stack exchange,提问作者ProodjePindakaas
相关产品推荐
相关产品推荐

