如何管控多计算任务?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




