You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程中实现tqdm进度条无重复原地更新

解决多进程下tqdm进度条重复/混乱的问题

我太懂这种烦躁感了——跑几个小时的多进程任务,结果进度条挤成一团根本没法看。这个问题主要是多进程输出没同步,再加上进度条的更新逻辑和位置控制没做对,咱们直接来改好它:

问题根源拆解

  1. update用法错误:你原来的progressbar.update(i)是错的——tqdm的update()接收的是进度增量,不是当前进度值,每次完成一个任务应该传1而非i。
  2. 无输出锁机制:多进程同时往stdout写内容,没有同步锁的话,进度条的输出会互相覆盖、错位。
  3. 位置控制缺保障:虽然指定了position=n_process,但没锁的话还是会出现进度条乱跑的情况。

修改后的可运行代码

from datetime import date, timedelta
from multiprocessing import Pool, Lock
from tqdm import tqdm

def some_func(date1):
    # 模拟耗时任务
    for i in range(1000000):
        pass

def load_data(args):
    date1, n_process, lock = args
    dLength = 100
    # 用lock同步多进程输出,position固定进度条的行位置
    with tqdm(total=dLength, position=n_process, lock=lock) as progressbar:
        for _ in range(dLength):
            some_func(date1)
            # 每完成一个任务,进度条前进1步
            progressbar.update(1)

if __name__ == '__main__':
    d1 = date(2018, 5, 22)
    d2 = date(2018, 5, 26)
    delta = d2 - d1
    dates_range = [d1 + timedelta(i) for i in range(delta.days + 1)]
    
    n_processes = 5
    # 创建全局锁,传给每个进程同步输出
    lock = Lock()
    # 打包任务参数:日期、进程位置、锁
    task_args = [(dates_range[i], i, lock) for i in range(min(n_processes, len(dates_range)))]
    
    with Pool(n_processes) as p:
        p.map(load_data, task_args)

核心改进说明

  • 全局输出锁:创建Lock对象并传入每个进程,tqdm的lock参数会用它来控制输出顺序,避免多个进度条同时写入导致混乱。
  • 正确的进度更新:每次调用progressbar.update(1),对应完成一个子任务,进度条稳步前进。
  • 固定行位置:position=n_process让每个进程的进度条固定在专属行,更新时只会修改本行内容,不会跑到其他行干扰。
  • 参数简化:把日期、位置、锁打包成元组用map传递,比starmap更简洁直观。

这样改完之后,每个进程的进度条会在独立的行里平稳更新,你能清晰追踪每个任务的执行进度啦!

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:11:58