multiprocessing下tqdm嵌套进度条稳定保留显示方案问询
多进程双层进度条实现方案(保留内层完成状态)
需求与问题
使用multiprocessing执行批量耗时任务时,需要:
- 外层进度条追踪总完成任务数量
- 内层进度条展示单个任务的实时进度,且任务完成后保留进度条的完成状态
当前遇到的问题:
- 内层进度条设置
leave=False:任务完成后进度条自动消失,无法保留状态 - 设置
leave=True:后续无法在同一位置重启新的内层进度条 - 手动打印完成进度条的方案依赖
sleep延迟,需根据设备/进程数调整,稳定性差
解决方案
核心思路是利用进程锁避免多进程输出冲突,通过手动控制tqdm的leave参数,在内层任务完成后保留进度条状态。
改进后的代码
from tqdm import tqdm from time import sleep import multiprocessing def do_the_thing(my_args, lock): if my_args: # 初始化内层进度条,固定位置为第二行,暂不保留 with lock: pbar_inner = tqdm(total=15, position=1, leave=False, bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [Task finished]') # 模拟任务执行,逐次更新进度 for i in range(15): sleep(.1) with lock: pbar_inner.update() # 任务完成后,设置leave=True并关闭,保留进度条状态 with lock: pbar_inner.leave = True pbar_inner.close() else: # 无进度条的任务,直接模拟耗时 sleep(1.5) if __name__ == '__main__': # 创建进程锁,同步多进程的控制台输出 output_lock = multiprocessing.Lock() # 外层进度条:追踪总任务完成数,固定在第一行 pbar_outer = tqdm(total=60, position=0, leave=True, bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [Total task progress]') for _ in range(3): # 初始化进程池,传递锁给tqdm确保输出同步 pool = multiprocessing.Pool(2, initializer=tqdm.set_lock, initargs=(output_lock,)) # 构造任务参数:每8个任务中有1个需要展示内层进度 task_args = [(True if i % 8 == 0 else False, output_lock) for i in range(20)] # 执行任务,更新外层进度条 for _ in pool.imap_unordered(lambda x: do_the_thing(*x), task_args): pbar_outer.update() pool.close() pool.join() pbar_outer.close()
关键说明
进程锁同步:
- 使用
multiprocessing.Lock()避免多进程同时向控制台输出,防止进度条混乱 - 进程池初始化时通过
tqdm.set_lock将锁传递给所有tqdm实例
- 使用
内层进度条控制:
- 初始化时
leave=False,避免任务未完成时保留进度条 - 任务完成后手动设置
pbar_inner.leave = True再关闭,让进度条保留在控制台中 - 固定
position=1,确保所有内层进度条都在同一位置显示,完成后覆盖旧状态同时保留最新完成信息
- 初始化时
外层进度条:
- 固定
position=0,始终显示在控制台第一行,追踪总任务完成量
- 固定
内容的提问来源于stack exchange,提问作者Taw
相关产品推荐
相关产品推荐

