电话
400 9058 355
多线程共用 Progress 实例会崩溃,因 Console 非线程安全且 Progress 共享状态未加锁;应使用 thread-safe Console + 独立 task_id 隔离更新,并统一所有输出到该 Console。
直接在多个线程里调用同一个 Progress 对象的 update() 或 advance(),大概率触发 RuntimeError: Working outside of application context(尤其搭配 Console 的非主线程刷新)或更隐蔽的显示错乱、卡死。根本原因是 rich.console.Console 默认不是线程安全的,且 Progress 内部共享状态(如任务列表、渲染计时器)未加锁。
核心是让所有线程共用一个线程安全的 Console 实例,并通过 add_task() 为每个线程分配独立 task_id,再用该 ID 更新——避免状态竞争。关键点:
Console 必须显式传入 force_terminal=True, color_system="truecolor" 等参数,并设置 soft_wrap=True(减少渲染冲突)Progress 时,传入这个共享 Console;各线程只调用 update(task_id, advance=1),绝不调用 add_task() 或修改任务元数据Progress 启动后(即进入 with progress: 块)才能开始更新,否则 task_id 无效示例:
from rich.progress import Progress from rich.console import Console from threading import Thread import timeconsole = Console(force_terminal=True, soft_wrap=True) progress = Progress(console=console)
def worker(taskid, n): for in range(n): time.sleep(0.1) progress.update(task_id, advance=1) # 安全:只更新自己 task
with progress: task1 = progress.add_task("[red]Thread-1", total=10) task2 = progress.add_task("[blue]Thread-2", total=15)
t1 = Thread(target=worker, args=(task1, 10)) t2 = Thread(target=worker, args=(task2, 15)) t1.start(); t2.start() t1.join(); t2.join()替代方案:用 multiprocessing.Manager 共享进度值(适合进程间)
如果实际用的是
multiprocessing(而非threading),Progress本身不支持跨进程。此时需绕过 UI 层,用Manager.dict()或Value同步原始进度数值,再由主线程轮询更新 UI:
shared_dict['task1'] = 7 这类键值对
Progress 的 refresh_per_second 控制下定期读取并调用 update(task_id, completed=shared_dict['task1'])
refresh_per_second=4 起步多线程中若任一线程

print() 或未绑定到同一 Console 的 rich.print(),会强行换行、挤占进度条空间,导致显示撕裂。必须统一:
console.print()
print()
Console
线程安全的底线不是“能跑”,而是“每次刷新都看到一致、完整、不跳动的进度行”——这要求从 console 初始化、task 分配到日志输出全部收口。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...