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

使用asyncio启动同步后台任务,能否实现六任务并发运行?

问题解答

首先得先修正你代码里的几个语法错误,不然根本跑不起来:

  • functools.partial(foo2(), i) 这里错把foo2的调用结果传给了partial,应该直接传foo2函数本身,改成functools.partial(foo2, i)
  • await asyncio.wait_for(...) 的括号不匹配,缺少右括号
  • main函数里没有等待所有后台任务完成的逻辑,会导致程序直接退出,任务还没执行完

修正后的代码大概是这样:

import asyncio
import functools
import time

def foo2(num):
    # 模拟阻塞代码,比如休眠2秒
    print(f"任务 {num} 开始执行")
    time.sleep(2)
    print(f"任务 {num} 执行完成")
    return num

async def foo1(i):
    loop = asyncio.get_running_loop()
    try:
        await asyncio.wait_for(
            loop.run_in_executor(None, functools.partial(foo2, i)),
            timeout=60
        )
    except asyncio.TimeoutError:
        print(f"任务 {i} 超时")

async def main():
    background_t = set()
    for i in range(6):
        task = asyncio.create_task(foo1(i))
        background_t.add(task)
    # 等待所有后台任务完成
    await asyncio.gather(*background_t)

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

回到你的问题:这种修正后的模式是可以让六个同步阻塞任务实现并发运行的。

原因很简单:

  • loop.run_in_executor 默认会使用ThreadPoolExecutor,把同步阻塞的foo2提交到线程池的线程里执行
  • 每个foo1任务在调用await loop.run_in_executor(...)时,会把控制权交还给asyncio事件循环,事件循环可以调度其他foo1任务执行,进而把对应的foo2也提交到线程池
  • 线程池里的多个线程会并行执行这些foo2阻塞任务,最终实现六个任务的并发运行

你可以跑一下上面的修正代码,会看到六个任务几乎同时开始,2秒左右全部完成,而不是串行执行需要12秒,这就证明了并发效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:07:14