🚀 Python 协程,一篇彻底搞懂(对比 JS)

12 阅读3分钟

协程 = 高并发的核心能力


🧠 一句话理解协程

协程 = 可以“暂停 + 恢复”的函数(且不会阻塞程序)

它的核心价值只有一个:

👉 在等待时,不浪费 CPU,而是去干别的事


📌 1. 协程长什么样?

普通函数

def func():
    return 1

协程函数

import asyncio

async def func():  # 加 async 就变协程
    await asyncio.sleep(1)
    return 1

✔️ 关键点:

  • async:定义协程函数
  • await暂停执行

⚡ 2. 协程的本质:可以“让出 CPU”

普通函数:

执行 → 执行 → 执行 → 结束(不能停)

协程函数:

执行 → 遇到 await → 暂停 → 切走 → 再回来继续

🎬 3. 图解:协程调度过程(重点!)

假设有 3 个任务:

async def task1():
    await asyncio.sleep(2)

async def task2():
    await asyncio.sleep(2)

async def task3():
    await asyncio.sleep(2)

🧾 执行时间线:

时间轴 →
a: |───────await───────| (2秒)
b:     |───────await───────|
c:         |───────await───────|

--------------------------------
总耗时 ≈ 2秒(不是 6 秒)

❗ 为什么只要 2 秒?

因为:

👉 await 不是“傻等”,而是:

主动把 CPU 让出去

执行流程其实是:

执行 task1 → 遇到 await → 挂起
执行 task2 → 遇到 await → 挂起
执行 task3 → 遇到 await → 挂起
↓
统一等待完成

🧪 4. 正确运行协程的方式

❌ 错误写法(不会执行)

task1()

✅ 正确写法

asyncio.run(task1())

🚀 5. 多协程并发(真实用法)

import asyncio

async def task(name):
    print(f"开始 {name}")
    await asyncio.sleep(2)
    print(f"结束 {name}")

async def main():
    await asyncio.gather(
        task("A"),
        task("B"),
        task("C")
    )

asyncio.run(main())

✔️ 结果:3个任务同时跑,只耗时 2 秒


🧠 6. 协程 ≠ 多线程(很多人搞错)

对比协程线程
切换方式主动(await)被动(系统调度)
开销极低较高
数量几万没问题几百就吃力
控制权开发者操作系统

👉 结论:

协程是“可控的并发”


⚔️ 7. Python vs JS 的 await(核心区别)

很多前端转 Python 会踩坑,这里直接讲本质👇


🟨 JavaScript 的 await

async function test() {
  await fetchA()
  await fetchB()
}

执行逻辑:

A 执行完 → 再执行 B

👉 是串行的!


🟩 Python 的 await

await asyncio.gather(
    taskA(),
    taskB()
)

执行逻辑:

AB 同时执行

👉 是并发的!


🎯 一句话总结区别

语言await 本质
JS等待结果
Python等待 + 让出 CPU

🔥 8. 更直观对比图

JS(串行 await)

A: |──────|
B:        |──────|

总时间:A + B

Python(协程并发)

A: |──────|
B: |──────|

总时间:max(A, B)

🚧 9. 常见误区(很重要)

❌ 误区 1:写了 async 就是并发

错!

await task1()
await task2()

👉 这是串行


✅ 正确并发写法

await asyncio.gather(task1(), task2())

❌ 误区 2:协程能加速 CPU 计算

错!

👉 协程只适合:

  • IO 操作(网络请求)
  • 数据库
  • 文件读写

不适合:

  • 大量计算(用多进程)

🧩 10. 我帮你补充一个更底层理解(重点)

你可以这样理解:

协程 = 用户态线程 + 手动调度

await 本质是:

yield 控制权

👉 把执行权交给事件循环(event loop)


🧠 最终总结(一定要记住)

协程的核心不是“异步”,而是:

✅ “在等待时,不阻塞”


🔑 记住这 3 点就够了:

  1. async:定义协程
  2. await:暂停 + 让出 CPU
  3. gather:实现并发

🎁 适用场景(非常关键)

协程最适合:

  • 爬虫(高并发请求)
  • AI Agent(多工具调用)
  • Web 后端(高并发接口)
  • 微服务调用

如果你接下来是要做:

👉 AI 智能体 / Agent 开发

那协程是必须掌握的核心能力之一(没有之一)。