多线程场景下如何解决tqdm进度条换行及位置错乱问题
tqdm多线程进度条异常的原因与解决方法
问题原因
tqdm默认通过终端光标位置更新进度条,多线程环境下每个tqdm实例独立操作光标,没有做线程同步。当某个线程的进度条完成(比如你的t2线程),它会将光标移到自身进度条的下一行,未结束的线程(t1)仍在更新进度条,光标操作互相干扰就会出现:
- 进度条交换位置:t2结束后光标移位,t1的进度条更新时占用了t2原来的位置,视觉上两者交换。
- 进度条重复打印:调整启动/join顺序后,光标位置混乱,t1的进度条更新时无法正确覆盖之前的行,从而重复输出。
解决方法
方法1:指定固定位置(适配原代码结构)
给每个线程的tqdm设置position参数,让每个进度条固定在终端特定行,避免光标干扰:
from tqdm import tqdm import time from threading import Thread def func1(): # 固定在第0行 for i in tqdm(range(20), position=0): time.sleep(0.1) def func2(): # 固定在第1行 for j in tqdm(range(20), position=1): time.sleep(0.3) t1 = Thread(target=func1) t2 = Thread(target=func2) t1.start() t2.start() t1.join() t2.join() # 清理进度条下方残留,将光标移到新行 print('\n' * 2) print('Completed')
方法2:使用tqdm官方多线程工具
用tqdm.contrib.concurrent.thread_map,它内部已处理线程同步,无需手动管理光标:
from tqdm.contrib.concurrent import thread_map import time def process_task(task_info): task_type, _ = task_info if task_type == "func1": time.sleep(0.1) else: time.sleep(0.3) # 构造任务列表,包含20个func1和20个func2任务 tasks = [("func1", i) for i in range(20)] + [("func2", j) for j in range(20)] # 启动多线程任务,自动生成进度条 thread_map(process_task, tasks, total=40) print('Completed')
内容的提问来源于stack exchange,提问作者B1smuth
相关产品推荐
相关产品推荐

