为何asyncio.TaskGroup未等待队列执行完成?total_slept_for值为0
解决asyncio任务总耗时计算为0的问题
你的代码中total_slept_for始终为0,核心问题是计时时机错误:asyncio.TaskGroup会自动等待所有创建的任务执行完毕,当你退出TaskGroup代码块时,所有worker已经处理完队列里的所有任务,后续的await q.join()几乎瞬间完成,因此计算出的时间差为0。
修正方案
把计时起点移到创建TaskGroup之前,利用TaskGroup自动等待任务完成的特性,直接在TaskGroup结束后计算时间差即可:
import asyncio import random import time async def worker(name, queue): while True: try: sleep_for = queue.get_nowait() except asyncio.QueueEmpty: break print(f"sleep_for : {sleep_for}") await asyncio.sleep(sleep_for) queue.task_done() print(f"{name} has slept for {sleep_for:.2f} seconds") async def main(): q = asyncio.Queue() total_sleep_time = 0 for _ in range(20): sleep_for = random.uniform(0.05, 1.0) total_sleep_time += sleep_for q.put_nowait(sleep_for) # 提前记录计时起点 started_at = time.monotonic() # TaskGroup会自动等待所有worker任务完成 async with asyncio.TaskGroup() as tg: for idx in range(3): tg.create_task(worker(f"worker-{idx}", q)) # 任务全部完成后计算总耗时 total_slept_for = time.monotonic() - started_at print("====") print(f"3 workers slept in parallel for {total_slept_for:.2f} seconds") print(f"total expected sleep time: {total_sleep_time:.2f} seconds") asyncio.run(main())
关键说明
asyncio.TaskGroup是Python 3.11+引入的特性,进入代码块后创建的任务会被自动管理,退出代码块时会等待所有任务执行完成,不需要额外调用await q.join()(不过如果保留await q.join()也不会出错,因为此时队列已经处理完毕)。- 将计时起点放在TaskGroup创建前,确保统计的是从所有任务开始执行到全部结束的完整耗时,这样就能得到正确的并行执行总时间。
内容的提问来源于stack exchange,提问作者yeov
相关产品推荐
相关产品推荐

