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

Python Asyncio原生协程疑惑:输出顺序为何与预期不符及学习资源

运行逻辑拆解

核心认知偏差说明

你预期和实际输出的差异,本质是对两个asyncio核心规则的理解不到位:

  • asyncio.create_task() 不是“定义一个待后续执行的任务”,而是调用后立刻把协程对象注册到事件循环的待调度队列,任务从这一刻起就进入可执行状态,根本不会等到后续代码await它的时候才启动
  • await 不是“阻塞CPU直到对应任务完成”,而是暂停当前所在协程的执行流程,把CPU控制权交回给事件循环,直到被等待的对象执行完成后,再从暂停的位置恢复当前协程的执行

全流程运行时序对应

顺着程序启动的每一步逻辑走,就能完全对应实际的输出结果:

  1. asyncio.run(main()) 初始化事件循环,驱动main协程开始执行
  2. 两次调用asyncio.create_task(),把3秒延时的say_after("A")(task1)、2秒延时的say_after("B")(task2)加入事件循环的待执行队列;main协程此时不会中断,会继续向下执行同步代码
  3. 执行同步语句print("----0"),这是程序的第一行输出
  4. main协程执行到await task1,主动暂停自身执行,把控制权交回事件循环;事件循环开始调度队列中已经待命的两个任务:
    • task1运行到内部的await asyncio.sleep(3),把自己挂起3秒,全程不占用CPU
    • task2运行到内部的await asyncio.sleep(2),把自己挂起2秒,全程不占用CPU
  5. 事件循环持续监控挂起任务的状态:2秒先到达等待阈值,task2被唤醒,执行内部的print(what),打印B
  6. 再经过1秒,task1的3秒等待到期,被唤醒执行内部的print(what),打印A;此时task1已经执行完毕,main协程中await task1的等待条件满足,main被唤醒
  7. main协程恢复执行,运行print("----1")
  8. 执行到await task2时,发现task2早在2秒时就已经全部执行完成,等待瞬间结束,程序正常退出

以上流程完全匹配实际的输出顺序,不存在逻辑偏差。

原生协程学习的实用示例获取渠道

你可以从这些方向找不依赖第三方异步框架、可直接运行的原生协程学习材料:

  • Python官方asyncio模块文档中的递进式示例,覆盖基础协程创建、任务调度、并发控制、异常捕获、任务取消全流程,是最贴合协程设计初衷的学习内容
  • Stack Overflow平台下asyncio标签的高赞问题配套代码片段,都是实际开发中踩坑总结的可复现场景,比如协程阻塞排查、多任务超时控制、协程间消息传递等实用内容
  • 聚焦Python 3.7+标准asyncio用法的技术书籍配套章节示例,避开早期基于生成器实现的老版本协程写法,优先学习基于asyncio.run()、create_task()等现代API的代码
  • 开源项目中仅使用asyncio标准库实现的功能模块,比如异步批量任务处理、异步定时调度这类场景的原生实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 04:57:03