为何time=1时func2晚启动却先于func1输出?async函数疑问
关于Python asyncio异步函数执行顺序的疑问
代码示例
import asyncio async def func1(): await asyncio.sleep(1) print("func1") async def func2(): await asyncio.sleep(time) print("func2") async def func3(): await asyncio.sleep(3) print("func3") async def main(): asyncio.create_task(func1()) await func2() await func3() asyncio.run(main())
不同参数下的输出
- 当
time = 1时,输出:
func2 func1 func3
- 当
time = 2时,输出:
func1 func2 func3
疑问
第一种情况中,为何func2启动晚于func1,却先输出?
解答
核心要搞清楚asyncio的任务调度和控制权流转逻辑:
任务创建与控制权的时机:
- 执行
asyncio.create_task(func1())时,只是把func1封装成任务加入事件循环的任务队列,但此时main协程还在运行,没有让出控制权,所以func1的代码根本还没开始执行。 - 直到main执行到
await func2(),func2开始运行,遇到await asyncio.sleep(1)才会把控制权交还给事件循环,这时候事件循环才会去调度func1开始执行。
- 执行
time=1时的执行细节:
- func2先进入
sleep(1)挂起,随后func1才开始执行并进入sleep(1)挂起。两者的等待时长都是1秒,但func2的sleep更早进入等待状态。 - 当两个任务的sleep同时到期时,默认事件循环的调度规则是优先唤醒更早进入等待的任务。所以func2会先被唤醒,执行
print("func2"),之后才轮到func1被唤醒执行打印。
- func2先进入
time=2时的差异:
- func2进入
sleep(2)挂起后,func1开始执行并进入sleep(1)挂起。1秒后func1的sleep先到期,被唤醒打印;再过1秒func2的sleep才到期,随后打印,所以顺序反过来。
- func2进入
内容的提问来源于stack exchange,提问作者Kumar Ayaman
相关产品推荐
相关产品推荐

