这是 Python 异步编程中最关键的基础之一:协程(Coroutine)、线程(Thread)、进程(Process),弄清楚这三者的区别和联系,以后学异步、多线程、多进程、协程、asyncio、并发编程就容易太多了!
🎯一句话总结(先看整体框架):
名称 | 执行单位 | 是否并发执行 | 启动成本 | 是否共享内存 | 常用场景 |
---|---|---|---|---|---|
进程 | 独立的程序 | ✅ 真并行 | 🚀 高 | ❌ 不共享 | 多核计算/CPU密集型 |
线程 | 进程内的子任务 | ✅ 并发(伪) | 🧵 中 | ✅ 共享 | 网络/爬虫/IO密集 |
协程 | 单线程内的子任务 | ✅ 并发(伪) | 🪶 极低 | ✅ 共享 | 网络/异步任务 |
🧠 一步一步搞懂这三者:用通俗例子讲
1️⃣ 进程(Process):一个独立的程序,拥有自己的一套资源
✅ 举个例子:
假设你是医院的IT主管,你开了:
- 一个微信 → 用来看消息(是一个进程)
- 一个浏览器 → 打开知乎查阅资料(另一个进程)
- 一个 Excel → 记录医药数据(再一个进程)
每个进程独立运行,互不干扰。它们之间不能直接互相读取对方内存(要靠进程间通信 IPC)。
2️⃣ 线程(Thread):进程内的“小员工”,共享资源,但能同时做事
✅ 举个例子:
你开了 Excel(一个进程),你可以同时:
- 输入数据
- 自动保存
- 后台算公式
这些动作在“一个 Excel”这个进程里,但由不同线程来做 —— 它们共享数据(比如你输的数字),但可以同时并发执行多个任务。
3️⃣ 协程(Coroutine):线程内的“自愿轮流执行”的小任务
✅ 举个例子:
你开了一个微信(进程),里面同时打开了多个聊天窗口(不同的“协程”):
- 正在回复一个病人的消息
- 同时等待另一个人发语音
- 还有一个窗口你等着回复文件
这些窗口看起来都在“同时进行”,但其实它们在一个线程里轮流执行 —— 谁遇到“要等待”的事情(比如收语音),就让出机会给其他窗口先处理。
🔍 更专业地比较(带关键点):
对比维度 | 协程 Coroutine | 线程 Thread | 进程 Process |
---|---|---|---|
是否并发 | ✅ 是(伪并发) | ✅ 是(伪并发) | ✅ 是(真并发) |
底层机制 | 事件循环+切换 | 操作系统调度 | 操作系统调度 |
上下文切换开销 | 极小(几纳秒) | 中等(要保存寄存器等) | 大(要拷贝内存等) |
资源独立性 | 完全共享(超轻) | 共享内存 | 内存隔离(安全) |
编程难度 | ✅ 简单(好控制) | ❌ 稍难(注意锁) | ❌❌ 最复杂(IPC) |
适合场景 | IO密集,协作任务 | 网络/异步/下载 | 多核计算,安全高隔离 |
Python库 | asyncio , trio | threading | multiprocessing |
🧪 举个 Python 实例:
# 协程示例
import asyncio
async def task(name):
print(f"{name} 开始")
await asyncio.sleep(1) # 假装网络请求
print(f"{name} 结束")
async def main():
await asyncio.gather(
task("A"),
task("B"),
task("C")
)
asyncio.run(main())
- 这个例子里
task("A")
、task("B")
、task("C")
是三个协程,它们共享内存,但在一个线程中交替运行,执行到await
会让出控制权给其他任务。
❗重点理解:协程是“主动交出控制权”,线程和进程是“操作系统强制调度”
类别 | 控制权交出方式 | 并发类型 |
---|---|---|
协程 | 自愿交出(await) | 看起来并发 |
线程 | 操作系统控制 | 假并发(GIL 限制) |
进程 | 操作系统控制 | 真并发(多核支持) |
💡 理解:
- CPU 密集型任务(比如图像识别、大量运算)→ 用多进程
- IO 密集型任务(比如网络爬虫、数据库访问)→ 用协程 或 多线程
- 想省资源、轻量快速切换任务 → 用协程
✅ 总结一句话:
进程是独立的程序,线程是并发的小工人,协程是节约资源的自觉员工,三者都可以并发执行,但方式、开销和使用场景完全不同。