You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何管控多计算任务?asyncio子函数中await报错问题求解

解决异步代码嵌套与并行运行的问题

首先,你遇到的SyntaxError: 'await' outside async function错误原因很明确:嵌套的函数f()没有被定义为异步函数。在Python的asyncio体系里,await关键字只能出现在async def定义的函数内部,哪怕是嵌套在另一个异步函数里的子函数,只要要用到await,就必须也声明为async def

先修正你的测试代码

把嵌套函数改成异步函数,并且在父协程里await它,就能解决语法错误:

import asyncio

async def cor():
    async def f():  # 这里改成async def
        await asyncio.sleep(0)
    await f()  # 调用异步子函数需要用await

asyncio.run(cor())

如何让复杂代码段并行运行

要实现复杂逻辑的并行,核心是让asyncio的事件循环能够正确调度多个协程任务。常用的方法有两种:

1. 使用asyncio.gather()批量执行协程

如果有多个独立的复杂协程任务,可以把它们传入asyncio.gather(),事件循环会自动调度它们并行执行:

import asyncio

# 复杂任务1
async def complex_task_1():
    print("开始执行任务1")
    await asyncio.sleep(1)  # 模拟耗时操作
    print("任务1完成")
    return "任务1结果"

# 复杂任务2
async def complex_task_2():
    print("开始执行任务2")
    await asyncio.sleep(0.5)  # 模拟耗时操作
    print("任务2完成")
    return "任务2结果"

async def main():
    # 并行运行两个复杂任务
    results = await asyncio.gather(complex_task_1(), complex_task_2())
    print("所有任务结果:", results)

asyncio.run(main())

运行这段代码会看到两个任务几乎同时启动,而不是串行执行。

2. 使用asyncio.create_task()创建后台任务

如果需要在一个协程里触发另一个协程并行执行(而不是等待它完成),可以用create_task()把协程包装成Task对象,事件循环会在后台调度它:

import asyncio

async def long_running_task():
    print("后台任务启动")
    for i in range(3):
        await asyncio.sleep(1)
        print(f"后台任务执行中... {i+1}/3")
    print("后台任务完成")

async def main():
    # 创建后台任务,立即开始执行
    task = asyncio.create_task(long_running_task())
    
    # 执行主逻辑
    print("主逻辑开始执行")
    await asyncio.sleep(2)
    print("主逻辑完成")
    
    # 等待后台任务结束(可选,如果需要获取结果)
    await task

asyncio.run(main())

这里主逻辑和后台任务会并行运行,互不阻塞。

关于asyncio.sleep(0)的补充

asyncio.sleep(0)确实可以让出当前协程的控制权,让事件循环去调度其他就绪的协程,但它的作用是触发一次事件循环的调度,前提是你的代码本身是正确的异步结构(所有需要await的操作都在async函数里)。如果你的复杂代码里有同步阻塞的逻辑(比如长时间的CPU计算),asyncio.sleep(0)也帮不了你——这种情况需要用loop.run_in_executor()把同步代码放到线程池/进程池里执行,避免阻塞事件循环。

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

火山引擎 最新活动