Python Asyncio原生协程疑惑:输出顺序为何与预期不符及学习资源
运行逻辑拆解
核心认知偏差说明
你预期和实际输出的差异,本质是对两个asyncio核心规则的理解不到位:
asyncio.create_task()不是“定义一个待后续执行的任务”,而是调用后立刻把协程对象注册到事件循环的待调度队列,任务从这一刻起就进入可执行状态,根本不会等到后续代码await它的时候才启动await不是“阻塞CPU直到对应任务完成”,而是暂停当前所在协程的执行流程,把CPU控制权交回给事件循环,直到被等待的对象执行完成后,再从暂停的位置恢复当前协程的执行
全流程运行时序对应
顺着程序启动的每一步逻辑走,就能完全对应实际的输出结果:
asyncio.run(main())初始化事件循环,驱动main协程开始执行- 两次调用
asyncio.create_task(),把3秒延时的say_after("A")(task1)、2秒延时的say_after("B")(task2)加入事件循环的待执行队列;main协程此时不会中断,会继续向下执行同步代码 - 执行同步语句
print("----0"),这是程序的第一行输出 - main协程执行到
await task1,主动暂停自身执行,把控制权交回事件循环;事件循环开始调度队列中已经待命的两个任务:- task1运行到内部的
await asyncio.sleep(3),把自己挂起3秒,全程不占用CPU - task2运行到内部的
await asyncio.sleep(2),把自己挂起2秒,全程不占用CPU
- task1运行到内部的
- 事件循环持续监控挂起任务的状态:2秒先到达等待阈值,task2被唤醒,执行内部的
print(what),打印B - 再经过1秒,task1的3秒等待到期,被唤醒执行内部的
print(what),打印A;此时task1已经执行完毕,main协程中await task1的等待条件满足,main被唤醒 - main协程恢复执行,运行
print("----1") - 执行到
await task2时,发现task2早在2秒时就已经全部执行完成,等待瞬间结束,程序正常退出
以上流程完全匹配实际的输出顺序,不存在逻辑偏差。
原生协程学习的实用示例获取渠道
你可以从这些方向找不依赖第三方异步框架、可直接运行的原生协程学习材料:
- Python官方asyncio模块文档中的递进式示例,覆盖基础协程创建、任务调度、并发控制、异常捕获、任务取消全流程,是最贴合协程设计初衷的学习内容
- Stack Overflow平台下asyncio标签的高赞问题配套代码片段,都是实际开发中踩坑总结的可复现场景,比如协程阻塞排查、多任务超时控制、协程间消息传递等实用内容
- 聚焦Python 3.7+标准asyncio用法的技术书籍配套章节示例,避开早期基于生成器实现的老版本协程写法,优先学习基于
asyncio.run()、create_task()等现代API的代码 - 开源项目中仅使用asyncio标准库实现的功能模块,比如异步批量任务处理、异步定时调度这类场景的原生实现
内容的提问来源于stack exchange,提问作者BYEONGJO KIM
相关产品推荐
相关产品推荐

