进程、线程、协程是后端面试的高频考点,也是理解并发编程的基础。这篇文章把三者的区别、原理和面试答题思路一次讲清楚。

进程(Process)

操作系统分配资源的基本单位。每个进程有独立的内存空间(代码段、数据段、堆、栈),进程之间互相隔离。

  • 创建开销大(要分配独立内存、初始化各种资源)
  • 崩了不影响其他进程
  • 通信麻烦,要走 IPC(管道、消息队列、共享内存等)

类比: 每个进程是一个独立的工厂,有自己的厂房和设备。

线程(Thread)

CPU 调度的基本单位。线程是进程内的执行单元,同一进程的线程共享内存空间(堆、全局变量),但每个线程有自己的栈和寄存器。

  • 创建开销比进程小
  • 共享内存,通信方便,但要处理并发安全(锁、同步)
  • 一个线程崩了可能拖垮整个进程

类比: 同一工厂里的多个工人,共用厂房和设备,但各自有自己的工作台。

协程(Coroutine)

用户态的轻量级”线程”,由程序自己调度,不依赖操作系统。协程在单线程内运行,遇到 I/O 等待时主动让出 CPU,切换到其他协程继续跑。

  • 创建和切换开销极小(不涉及内核态切换)
  • 没有线程安全问题(单线程内跑)
  • 适合 I/O 密集型场景(网络请求、数据库查询)
  • 不适合 CPU 密集型(单线程跑满 CPU,其他协程都卡着)

类比: 一个工人同时处理多件事,做 A 的时候等材料,就先去做 B,材料到了再回来继续 A。

三者对比

进程 线程 协程
调度者 操作系统 操作系统 用户程序
内存 独立 共享(同进程) 共享(同线程)
切换开销 极小
并发安全 天然隔离 需要加锁 单线程无竞争
适合场景 隔离性要求高 CPU 密集 + 多核 I/O 密集

面试常问的延伸点

为什么协程切换比线程快?

线程切换需要进入内核态,保存/恢复寄存器、切换页表等,开销在微秒级。协程切换在用户态完成,只需保存少量寄存器,开销在纳秒级。

Go 的 goroutine 是协程吗?

是协程的变体,但 Go runtime 会把 goroutine 调度到多个系统线程上跑(M:N 模型),所以能利用多核,比传统协程更强。

Python 的 asyncio 是协程吗?

是,基于事件循环的协程,单线程,遇到 await 就切换。适合网络 I/O,但 CPU 密集任务还是要用多进程(绕过 GIL)。


理解这三者的本质区别,再去看并发编程、异步框架、Go/Python 的并发模型,会清晰很多。