Part II · 一台机器 · 第 4 章
04

同时做很多事:并发

并发不是让代码变快的咒语,而是让多个执行流共享资源的纪律。它让云服务能扛住很多请求,也让最隐蔽的 bug 诞生。

难度 CS162 核心 用时 约 55 分钟 交互 竞态流程 · 锁策略取舍 路线 螺旋式:先抓大图,再深入机制

0先把地图摊开

并发不是让代码变快的咒语,而是让多个执行流共享资源的纪律。它让云服务能扛住很多请求,也让最隐蔽的 bug 诞生。 本章不会把概念排成术语表,而是沿着一条真实系统路径走:先看它解决什么痛点,再看 OS/云平台怎样实现,最后回到工程取舍。

竞态结果依赖不同线程交错顺序的 bug。
临界区访问共享状态、必须被保护的一段代码。
让同一时刻只有一个执行流进入临界区的工具。
死锁多个执行流互相等待对方释放资源,谁也走不了。
同时做很多事:并发 · 核心流程 分步动画 点击节点或用键盘 ← →
图 4.1核心机制路径。把这一章最容易散掉的流程压成可播放的五步。

4.1并发解决的是等待,不是魔法

Web 服务的大多数时间不是在算,而是在等网络、磁盘、数据库。并发让一个请求等待时,CPU 可以处理别的请求。它提高资源利用率,但也把共享状态暴露在复杂交错里。

4.2线程共享内存,所以危险

两个线程读写同一个变量,如果没有同步,结果可能取决于调度器在纳秒级做出的切换。你本地跑一万次没复现,不代表生产不会在凌晨复现。

4.3锁让秩序回来,也让性能下降

锁把临界区串行化,恢复正确性,却可能制造排队。粒度太粗,吞吐低;粒度太细,复杂且容易死锁。工程里的锁设计,几乎都是在正确性与并行度之间找边界。

4.4从锁到消息,再到无状态服务

云服务常把状态推到数据库、缓存或队列里,避免所有 worker 共享内存。actor、消息队列、事件驱动不是换个时髦词,而是在减少共享可变状态。

4.5并发是分布式的预告片

单机并发已经很难,因为线程共享时间和内存。分布式系统更难,因为机器还会丢消息、时钟不同步、节点故障。第 10 章会把这些痛苦放大。

同时做很多事:并发 · 取舍实验 可玩模拟器 切换策略,看指标怎么变
图 4.2工程取舍。云和 OS 的概念真正进入工程时,几乎都不是“选最好”,而是在约束之间找一个诚实的点。

云与 OS 的桥

这一章不是孤立知识点。下面这张表把它和前后章节接起来:你会看到,同一个机制在单机、云平台和 AI 基建里会换名字,但问题结构没变。

本章机制云上形态为什么重要
锁/临界区数据库事务、分布式锁单机互斥扩展到多机后,故障会让问题变得更锋利。
线程池Web worker、serverless concurrency并发度过高会把下游打爆,过低会浪费机器。
无状态Kubernetes 水平扩缩容只有无状态 worker 才能轻松复制和替换。
深潜 读完本章后,怎么确认自己真的懂了?

不要只背定义。你应该能把一个线上现象翻译回机制:慢在哪里、谁在排队、哪个抽象漏了、哪个资源被过度承诺。下面三个检查点可以当成小作业。

本章收束 · 你现在握住了什么

  • 并发的收益来自利用等待时间,风险来自共享可变状态。
  • 竞态是交错顺序影响结果;锁通过禁止危险交错恢复正确性。
  • 锁粒度越细,潜在并行度越高,复杂度和死锁风险也越高。
  • 云架构常用无状态、队列和外部存储来减少共享内存。

接下来我们看程序如何与外部世界对话:文件、网络、磁盘,以及为什么一次 fsync 能改变系统命运。