如何实现在Python异步代码中监控任务进度_利用tqdm与异步队列同步状态

夜伟大大_8363

夜伟大大_8363

2026-06-01

206人浏览

原创

tqdm在异步任务中不自动更新是因为其默认依赖同步阻塞机制,而asyncio需显式让出控制权或借助tqdm.asyncio/队列机制触发display()。

如何实现在python异步代码中监控任务进度_利用tqdm与异步队列同步状态

为什么 tqdm 在异步任务里不自动更新?

tqdm 默认依赖同步的 time.sleep 或阻塞式迭代来触发进度条刷新,而 asyncio 任务在事件循环中非阻塞运行,tqdm.update() 调用若不在主线程或未主动让出控制权,UI 就卡住不动。这不是 bug,是调度模型差异导致的——你看到的“静止进度条”,其实是 tqdm 的 display() 没被及时调用。

常见错误现象:async for 遍历异步生成器时套 tqdm(async_iter),结果进度条只在最后刷出 100%;或者手动调 pbar.update(1) 却没效果。

  • 不要直接把异步迭代器传给 tqdm(),它不识别 __aiter__
  • 避免在协程内部频繁调 pbar.update() 而不配合 await asyncio.sleep(0) 让出控制权
  • tqdm 实例必须在主线程创建,且其 display() 需由主线程/事件循环驱动(推荐用 asyncio.to_thread 或定时刷新)

用 asyncio.Queue + tqdm 手动同步进度

核心思路:生产者协程往 asyncio.Queue 推送已完成任务标识(如 ID 或计数),消费者在主线程用 asyncio.create_task 启动一个“刷新协程”,定期从队列取值并调 pbar.update()。这样解耦了异步执行和 UI 更新线程。

实操要点:

  • 初始化 pbar = tqdm(total=N, unit="task") 前先确定总任务数(动态总数需预估或用 pbar.total += 1 动态扩容)
  • 队列设为 asyncio.Queue(maxsize=0),避免生产者因满队列挂起
  • 刷新协程用 while True + await queue.get() 阻塞监听,每次取到就 pbar.update(1),再 queue.task_done()
  • 主逻辑结束前调 await queue.join() 确保所有完成信号已处理

示例关键片段:

pbar = tqdm(total=len(tasks), unit="task")
queue = asyncio.Queue()
<p>async def worker(task_id):
await asyncio.sleep(0.1)  # 模拟异步工作
await queue.put(1)  # 发送完成信号</p><p>async def monitor_progress():
while True:
await queue.get()
pbar.update(1)
queue.task_done()</p><h1>启动监控协程</h1><p>asyncio.create_task(monitor_progress())</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9965" title="macOS UI 自动化技能包 —— 用 Python 控制你的 Mac"><img
														src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="macOS UI 自动化技能包 —— 用 Python 控制你的 Mac" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill9965" title="macOS UI 自动化技能包 —— 用 Python 控制你的 Mac" class="overflowclass">macOS UI 自动化技能包 —— 用 Python 控制你的 Mac</a>
													<p class="overflowclass">让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript

系统要求
macOS 14+ (Sonoma)

Python 3.9+

需要开启:辅助功能 + 屏幕录制权限</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill9965" title="macOS UI 自动化技能包 —— 用 Python 控制你的 Mac" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div><p>await asyncio.gather(*[worker(i) for i in range(len(tasks))])
await queue.join()  # 等待所有信号处理完
pbar.close()</p>

用 tqdm.asyncio 替代手写队列(Python ≥ 3.11 + tqdm ≥ 4.66)

新版 tqdm 内置了 tqdm.asyncio 模块,专为异步场景优化,底层用 asyncio.to_thread 把 display() 转发到线程池,避免阻塞事件循环。它不是魔法,但省去了队列胶水代码。

使用前提与限制:

  • 必须用 async for item in tqdm.asyncio.tqdm(async_iterable),不能用普通 tqdm() 包裹
  • async_iterable 必须实现 __aiter__(如 async_generator、aiofiles 文件对象)
  • 不支持直接传 list 或 range,得包装成异步生成器:
async def async_range(n):
    for i in range(n):
        await asyncio.sleep(0)  # 让出控制权
        yield i
<p>async for _ in tqdm.asyncio.tqdm(async_range(100), total=100):
await do_work()</p>

性能提示:每轮迭代都触发一次线程切换,高频小任务(如毫秒级)可能比纯队列方案慢 10–20%,但代码简洁性提升明显。

进度同步失败时优先检查这三处

多数“进度条不动”问题不在于逻辑,而在于调度链路断点。按顺序快速验证:

  • 确认 pbar.update() 是否真被调用(加 print(f"updated: {pbar.n}") 测试)
  • 检查事件循环是否仍在运行——如果主协程 await 结束后没 await queue.join() 或没 await 监控协程,刷新协程可能已被取消
  • 验证 tqdm 输出流是否被重定向(如 Jupyter 中 sys.stdout 被捕获、或日志库覆盖了 sys.stderr),可临时加 file=sys.stdout 强制输出位置

异步进度监控的本质,是把“状态变更”和“状态呈现”拆到两个协作的调度上下文中。队列是显式通道,tqdm.asyncio 是隐式封装,选哪个取决于你愿不愿意为可读性多写几行,还是为可控性多管一层线程。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1831

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4944

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1789

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

29677

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3527

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3547

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1223

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

616

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2763

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习