跳到主内容
快讯直播
AI智模界
AI 词典

进程与线程:为什么 Python 的并发总要分两种情况说

一句话定义:进程(Process)是操作系统分配资源的最小单位,线程(Thread)是操作系统调度 CPU 的最小单位。一个进程里可以容纳多个线程,它们共享这个进程的内存空间。

打个比方:进程像一栋独立厂房,有自己的地皮和水电表,也就是独立的内存地址空间;线程则像厂房里的工人,共用同一间仓库。好处是拿东西方便,坏处是一个工人把仓库点着了,整栋厂房都得停工。厂房与厂房之间则互不影响。

对比项进程线程
内存各自独立共享所属进程的内存
创建 / 切换开销大小
通信方式需要序列化:管道、队列、共享内存直接读写同一变量,但要自己加锁
隔离性强,一个崩了不牵连别人弱,一个崩了整组陪葬
典型适用CPU 密集型、需要稳定隔离I/O 密集型、需要频繁共享数据

GIL 到底限制了谁:CPython 解释器里有一把全局锁,叫全局解释器锁(Global Interpreter Lock,GIL),它保证同一时刻只有一个线程在执行 Python 字节码。因此在一台多核机器上开多个线程做纯 Python 的循环计算,总耗时和单线程差不多,甚至更慢,因为线程切换本身有开销。这也是很多人说“Python 多线程是假的”的由来。

但这个说法只对了一半。GIL 不限制以下两种情况:

  • 等待型任务:读文件、发网络请求、查数据库时,线程会主动释放 GIL,别的线程照跑不误。所以爬虫、API 调用这类 I/O 密集型任务,多线程是有效的。
  • 会释放 GIL 的 C 扩展:NumPy 的矩阵运算、PyTorch 的底层算子,在 C/C++ 里计算期间通常不持有 GIL,多线程依然能并行。

所以 Python 的并发方案总得分两种情况讨论:I/O 密集型用多线程或协程(asyncio),写起来简单、开销小;CPU 密集型用多进程(multiprocessing),每个进程都有独立的解释器和自己的 GIL,能真正吃满多核,代价是进程间传数据要序列化、启动慢、内存占用成倍增加。

给从业者的操作建议:先判断瓶颈是“在等”还是“在算”。在等,就上线程或协程;在算,就上多进程。还有第三条路常被忽略:把热点循环换成向量化写法,交给 NumPy / PyTorch 这类底层会释放 GIL 的库,往往比换并发模型收益更大。另外线程和进程都不是越多越好,上下文切换和锁竞争会反过来吃掉收益。

一点补充:GIL 是 CPython 这个具体实现的产物,并非 Python 语言规范的规定,其他实现未必如此,具体行为以官方文档为准。真正跨语言的通用结论是那句老话:进程管隔离,线程管共享;要隔离就付通信成本,要共享就承担风险。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。