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

为何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())

关键说明

  1. asyncio.TaskGroup是Python 3.11+引入的特性,进入代码块后创建的任务会被自动管理,退出代码块时会等待所有任务执行完成,不需要额外调用await q.join()(不过如果保留await q.join()也不会出错,因为此时队列已经处理完毕)。
  2. 将计时起点放在TaskGroup创建前,确保统计的是从所有任务开始执行到全部结束的完整耗时,这样就能得到正确的并行执行总时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 12:07:09