1. 并发调度基础:进程与线程概念、GIL锁对Python并发的影响、并发与并行的区别

聊并发调度,得先从最基础的两个概念说起——进程和线程。我刚开始接触这块时,也经常搞混。说白了,进程是资源分配的最小单位,线程是CPU调度的最小单位。嗯,记住这句话,后面就好理解了。

1.1 进程与线程:到底差在哪?

进程就像一家独立的公司。有自己的办公场地(内存空间)、自己的财务(文件句柄)、自己的员工(线程)。每个进程之间互不干扰,一家公司倒闭了,不影响隔壁公司继续营业。

线程呢?就是公司里的员工。同一家公司的员工共享办公场地、共享打印机、共享茶水间。但问题也来了——如果两个员工同时要用打印机,就得排队,不然会乱套。这就是线程同步要解决的问题。

我在项目中遇到过这样一个场景:一个Web服务要处理大量用户请求。如果每个请求都开一个新进程,内存开销巨大,响应也慢。后来改成线程池,一个进程里开几十个线程,共享内存,切换成本低,吞吐量直接翻倍。

核心区别总结:

  • 资源开销:进程间切换成本高,线程间切换成本低
  • 内存隔离:进程有独立地址空间,线程共享进程内存
  • 通信方式:进程间通信(IPC)复杂,线程间通信简单(共享变量)
  • 健壮性:一个进程崩溃不影响其他进程;一个线程崩溃可能拖垮整个进程

1.2 GIL锁:Python并发的心头痛

说到Python并发,绕不开GIL(全局解释器锁)。你想想看,Python这么火的语言,为什么在CPU密集型任务上表现那么差?答案就是GIL。

GIL是什么?简单说,CPython解释器里有一把大锁。这把锁规定:同一时刻,只有一个线程能执行Python字节码。不管你开多少个线程,真正干活儿的只有一个。

为什么会这样?历史原因。Python的内存管理不是线程安全的。早期设计者为了省事,直接加了一把全局锁。嗯,这个设计在当时看来没问题,但现在成了性能瓶颈。

避坑指南:

我曾经在一个数据处理项目里,用多线程去加速计算。开了16个线程,结果CPU利用率只有12%左右。排查了半天,才发现是GIL在作祟。后来改用多进程,每个进程独立一个GIL,CPU利用率直接飙到95%以上。

GIL的影响分两种情况:

任务类型 GIL影响 推荐方案
CPU密集型(计算、加密、压缩) 严重,多线程几乎无加速 多进程(multiprocessing)
I/O密集型(网络请求、文件读写) 较小,I/O等待时释放GIL 多线程(threading)或异步(asyncio)

说白了,如果你的程序大部分时间在等I/O,多线程没问题。但如果是在做大量计算,多线程反而可能比单线程还慢——因为线程切换也有开销。

1.3 并发与并行:一字之差,天壤之别

这两个词经常被混用,但本质完全不同。我习惯用一个比喻来解释:

  • 并发:一个人同时处理多件事。比如你一边写代码一边听音乐,看起来是同时在做,实际上大脑在快速切换。
  • 并行:多个人各自处理一件事。比如你和同事同时写不同的代码模块,互不干扰。

在计算机里,单核CPU只能实现并发(时间片轮转),多核CPU才能实现真正的并行。你想想看,如果你的电脑是4核8线程,理论上最多可以并行执行8个任务。

注意:

并发不一定要并行。一个单核CPU照样可以跑几百个并发任务,只是看起来像同时执行而已。并行一定需要多核硬件支持。很多新手把并发等同于多线程,其实单线程异步也是并发的一种形式。

我在做调度系统时,就踩过这个坑。一开始设计成多线程并行处理任务,结果部署到2核的服务器上,性能还不如单线程。后来改成异步I/O + 多进程混合模式,才真正把硬件性能榨干。

1.4 知识体系总览

下面这张图,把本章的核心逻辑串起来了。我建议你多看几遍,理清关系。

并发调度基础 · 知识体系 并发调度 进程与线程 进程:资源分配最小单位 线程:CPU调度最小单位 GIL全局解释器锁 同一时刻仅一个线程执行 CPU密集→多进程 / I/O密集→多线程 并发 vs 并行 并发:逻辑上同时(单核可行) 并行:物理上同时(需多核) 理解这三块,才能设计出高效的并发调度方案 选对工具(进程/线程/异步)比盲目堆资源更重要

这张图把本章的三个核心知识点串起来了。从左到右分别是进程与线程、GIL锁、并发与并行。你看,它们不是孤立的——GIL锁直接影响了你该选进程还是线程,而并发与并行的区别决定了你的硬件资源能不能被充分利用。

我的建议:

刚开始学并发调度,别急着写代码。先把这三个概念理清楚。我见过太多人一上来就开几十个线程,结果性能反而下降,最后发现连GIL是什么都不知道。基础打牢了,后面学协程、锁、信号量这些才不费劲。

好了,这一章就到这里。记住:进程是公司,线程是员工,GIL是公司里那把唯一的钥匙,并发是聪明地安排工作,并行是真正地同时干活。把这些想明白了,后面的内容就好理解了。