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

如何在Python中按复杂依赖关系高效并发运行协程以最小化总耗时?

如何在Python中按复杂依赖关系高效并发运行协程以最小化总耗时?

这个场景我太熟了——要在满足依赖的前提下把并发效率拉满,核心就是让每个任务一满足前置条件就立刻启动,别让它被无关的任务拖着。针对你说的A、B、C、D的依赖关系,我们可以用asyncio.create_task来精准控制任务的启动时机,完全不需要用到容易搞乱的回调。

最优实现思路

  1. 先同时启动A和B的任务,让它们并行执行,互不等待
  2. 一旦A的结果出来,立刻启动C(不用等B完成)
  3. 等B的结果出来后,因为A已经完成,直接启动D
  4. 最后只需要等C和D都执行完毕即可

这样所有能并行的环节都不会浪费时间:A和B并行,C在A结束后立刻启动,D在A+B都结束后立刻启动,C和D也能并行运行,总耗时肯定是最小的。

完整代码示例

import asyncio

async def get_a():
    # 模拟A的耗时,比如2秒
    await asyncio.sleep(2)
    return "Result of A"

async def get_b():
    # 模拟B的耗时,比如3秒
    await asyncio.sleep(3)
    return "Result of B"

async def get_c(a_result):
    # 模拟C的耗时,比如1秒
    await asyncio.sleep(1)
    return f"Result of C (depends on {a_result})"

async def get_d(a_result, b_result):
    # 模拟D的耗时,比如1秒
    await asyncio.sleep(1)
    return f"Result of D (depends on {a_result} and {b_result})"

async def main():
    # 1. 同时启动A和B的任务,让它们并行跑
    task_a = asyncio.create_task(get_a())
    task_b = asyncio.create_task(get_b())
    
    # 2. 等A完成,拿到结果后立刻启动C
    a = await task_a
    task_c = asyncio.create_task(get_c(a))
    
    # 3. 等B完成,此时A已经完了,直接启动D
    b = await task_b
    task_d = asyncio.create_task(get_d(a, b))
    
    # 4. 最后等C和D都完成,拿到结果
    c, d = await asyncio.gather(task_c, task_d)
    
    print(c)
    print(d)

if __name__ == "__main__":
    asyncio.run(main())

为什么这个方案比你提到的两种更好?

  • 对比第一种用asyncio.gather(get_a(), get_b())的方式:这种方式要等A和B都完成才会继续,等于C要白白等B跑完的时间,完全浪费了并发空间
  • 对比第二种把A和C绑成一组和B并行的方式:这种方式下,D必须等C和B都完成才能启动——如果C比B慢很多,那D就要等C跑完才能开始,而实际上D只需要A和B的结果,完全不用等C

扩展到更复杂的依赖链

如果你的实际场景有更多任务、更复杂的依赖(比如E要等C和D,F要等B和E),这个思路也完全适用:

  • 每个任务都用create_task在满足依赖后立刻启动
  • 用await等待单个任务的结果,用来触发依赖它的任务
  • 最后用gather等待所有需要最终结果的任务完成

这种方式逻辑清晰,比回调好维护太多,每个环节的依赖关系一目了然。

备注:内容来源于stack exchange,提问作者Pwnosaurus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:43:06