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

Python多进程中如何在子进程内更新共享tqdm进度条?

解决多进程中子进程更新tqdm进度条的波动问题

你的问题根源在于直接将tqdm进度条对象传递给子进程:

  • 多进程间的对象是独立拷贝,子进程操作的pbar并不是主进程的进度条实例,更新操作无效且会导致终端输出混乱。
  • 主进程提前调用了pbar.close(),导致进度条提前终止,后续子进程的输出会破坏已关闭的进度条渲染。

正确的做法是:让子进程只负责任务执行,通过队列将进度更新信号发送给主进程,由主进程统一更新进度条(因为进度条属于主进程的终端输出上下文)。

修正后的代码

import multiprocessing as mp
import time
from tqdm import tqdm
import threading

def test(task_queue, update_queue):
    while True:
        x = task_queue.get()
        if x is None:
            break
        for i in range(x):
            time.sleep(0.1)  # 缩短睡眠方便测试
            # 子进程只发送更新信号,不直接操作进度条
            update_queue.put(1)

def update_progress(update_queue, pbar, total):
    """主进程的线程,负责监听更新队列并更新进度条"""
    updated = 0
    while updated < total:
        delta = update_queue.get()
        pbar.update(delta)
        updated += delta
    pbar.close()

if __name__ == "__main__":
    total_tasks = 5050
    task_queue = mp.Queue()
    update_queue = mp.Queue()  # 用于传递进度更新信号
    processes = []

    # 启动子进程
    for _ in range(4):
        p = mp.Process(target=test, args=(task_queue, update_queue))
        p.start()
        processes.append(p)

    # 主进程初始化进度条,并启动监听更新的线程
    pbar = tqdm(total=total_tasks)
    progress_thread = threading.Thread(target=update_progress, args=(update_queue, pbar, total_tasks))
    progress_thread.start()

    # 投递任务
    for idx in range(100):
        task_queue.put(idx)

    # 发送结束信号
    for _ in range(4):
        task_queue.put(None)

    # 等待子进程结束
    for p in processes:
        p.join()

    # 等待进度更新线程结束
    progress_thread.join()

关键改进点

  • 用update_queue作为子进程和主进程的通信桥梁,子进程只负责发送需要更新的进度增量。
  • 主进程启动单独线程监听更新队列,统一处理进度条更新,避免多进程直接操作终端的冲突。
  • 不再传递tqdm对象给子进程,也不提前关闭进度条,确保进度条生命周期覆盖整个任务流程。
  • 移除不必要的锁:mp.Queue本身是线程/进程安全的,无需额外加锁;进度条更新由单线程处理,也不会有竞争问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:15:40