<!-- title: 并发不是并行：一堂不过时的神课 -->
<!-- domain: programming -->

# 并发不是并行：重读 Rob Pike 那堂十年不过时的 Go 神课

> **概述**：在编程世界里，有一道分水岭把程序员分成两类：能把"并发（concurrency）”和“并行（parallelism）”说清楚的人，和说不清楚的人。这道分水岭的标志性界碑，是 Go 语言联合创始人 Rob Pike 在 2012 年 Heroku Waza 大会上的一堂约 30 分钟的演讲——*Concurrency Is Not Parallelism*。十多年过去，这堂课非但没有过时，反而被后来的结构化并发、Java 虚拟线程、Swift Actor 等技术演进逐一“补票验证”。本文带你完整吸收这堂课的论证结构、理论血脉与争议边界：没看过视频，你能看懂全部核心；看过视频，你会知道它哪里讲对了、哪里被讲歪了。

## 一、视频基本信息

| 项目 | 内容 |
|---|---|
| 标题（原文） | Concurrency Is Not Parallelism |
| 标题（中译） | 并发不是并行 |
| 演讲者 | Rob Pike（贝尔实验室出身，Unix / Plan 9 / UTF-8 核心成员，Go 语言联合创造者） |
| 频道 | Heroku 官方 YouTube 频道（另有多个会议方与社区转载版本） |
| 发布时间 | 2012 年 Heroku Waza 开发者大会现场演讲录像（精确上线日期据频道页面） |
| 时长 | 约 30 分钟 |
| 热度 | 常青经典：十多年来长期出现在 Hacker News、Reddit 等社区的“并发入门第一课”推荐清单中，每逢多核与异步话题的讨论都会被重新引用（精确播放数本次未能实时抓取，以频道页面为准） |
| 配套幻灯片 | Go 官网托管：go.dev/talks/2012/waza.slide |

*注：本文写作时未能实时抓取频道页面，凡无法核实的数据一律从略标注，未作任何精确数字的凭空标注。*

## 二、核心主张拆解：一堂课的五个论证步骤

### 1. 先把两个词钉死：结构 vs 执行

整堂课最著名的一句话，出现在演讲开篇的幻灯片上：

> "Concurrency is about **dealing with** lots of things at once. Parallelism is about **doing** lots of things at once."
> （并发是同时*应对*多件事，并行是同时*做成*多件事。）

Pike 的定义非常克制：**并发是一种程序结构方式**——把程序设计成多个可以独立推进的执行体，彼此通过消息协作；**并行是一种执行方式**——多个计算真的在同一个物理瞬间发生。关键推论是：**两者是正交的**。你可以写出结构上高度并发、但运行在单核上靠时间片轮转的程序（没有并行）；也可以有完全不做并发设计的并行（比如 GPU 上的数据并行、SIMD 指令）。

这句话之所以是分水岭，是因为它把一个物理问题（有没有多个核）和一个设计问题（程序怎么组织）拆开了。大多数“并发恐惧症”，源于把这两件事捆绑在一起想。

### 2. 硬件背景：为什么 2012 年人人都该听这堂课

演讲的时点选得极准。2005 年前后，处理器主频的红利基本见顶：功耗墙挡住了继续提频的路（芯片行业称之为“登纳德缩放定律”的失效），厂商集体转向“堆核数”的路线。同年，C++ 委员会元老 Herb Sutter 发表了那篇后来被引用了无数次的文章——《The Free Lunch Is Over》（免费午餐结束了），警告软件行业：过去几十年“什么都不做、程序自动变快”的时代终结了，以后想快，你必须写出能利用多核的程序。

Pike 在演讲中把这个背景一笔带过，却点出了更冷静的一层：**多核不是学习并发的唯一理由**。这直接引出第三步。

### 3. 最反直觉的主张：并发结构的价值，独立于并行

这是整堂课的灵魂，也是被最多听众忽略的部分。Pike 明确说：并发设计的目标首先是**让程序更易懂、更易组织**，并行只是良好并发结构带来的“可能的副产品”。

他的论据是：很多程序天然就是“同时应对多件事”的——服务器同时面对多个连接、编辑器同时响应输入和后台拼写检查、运行时同时做垃圾回收和业务计算。如果用传统单线程顺序模型去写，你得手写状态机、手动交错各种任务；而如果把每个独立任务写成一个并发的执行单元，程序结构就和问题结构对齐了——**哪怕最后只跑在一个核上**。演讲里他还专门展示了并发垃圾回收、图形界面响应这类例子：它们的收益是响应性和清晰度，不是吞吐量。

### 4. 用什么结构承载并发：从 Dijkstra 到 Go 的血脉

并发结构不止一种，Pike 给出的答案是 Go 的 CSP 路线：**goroutine（轻量执行体）+ channel（类型化管道）+ select（多路选择）**。他给出那句后来被写进 Go 官方格言的话（同样见于 Effective Go）：

> Don't communicate by sharing memory; share memory by communicating.
> （不要靠共享内存来通信，要靠通信来共享内存。）

翻译成工程语言：与其让多个线程围绕同一块可变内存加锁互搏，不如让数据“所有权”随消息在执行体之间流动——同一时刻只有一个执行体碰这块数据，锁就失去了存在的大半理由。

### 5. 演示与模式：地鼠、传送带与负载均衡

这堂课最出圈的，是那组地鼠（gopher）动画：要把一堆书搬走，你可以拆成“装车、运输、卸货”三段独立任务，用传送带（channel）连接；吞吐不够，就加地鼠（worker）、加传送带——任务分解、消息传递、扇入扇出、负载均衡，并发设计的全部基本动作，在动画里被压缩成几分钟的直觉。Pike 现场用 channel 手写了负载均衡器的骨架代码，演示了这套路数如何让“横向扩展”从一个分布式系统的宏大命题，退化为局部几行代码的组合。

## 三、知识与理论溯源：这堂课不是 Pike 发明的

理解这堂课的深层价值，必须看到它背后的半个多世纪的学术谱系——这也是它区别于“经验分享”的地方：

- **Dijkstra（1965）**：信号量与“协作顺序进程”的开山工作，奠定了并发正确性问题的基本语汇（互斥、死锁、饥饿）。
- **C.A.R. Hoare 的 CSP（1978）**：发表于《Communications of the ACM》的经典论文《Communicating Sequential Processes》，提出“顺序进程 + 通信原语”的并发模型，后来扩展成 1985 年的同名专著，成为进程代数（CCS、π 演算一支）的基石。
- **Occam 语言与 INMOS Transputer（1980 年代）**：Hoare 参与设计的 Occam 直接把 CSP 思想做成语言；Transputer 芯片则试图把“每核一进程、靠通道通信”做成硬件—— commercial 失败了，但思想存续。
- **贝尔实验室内脉**：Pike 本人在 1980–90 年代先后做了 Newsqueak、Alef、Limbo 三门实验语言，一步步打磨“轻量线程 + 通道”的手感，Go（2009 年 11 月开源发布）是这条内脉的集大成。换句话说，Go 的并发模型不是追新，而是一次四十年谱系的工程化落地。
- **Erlang（爱立信，1980 年代）**：Joe Armstrong 等人独立发展出的 Actor/邮箱模型，与 CSP 同为消息传递大家族。Pike 在演讲中明确把 Go 的模型与 Erlang 的“每进程一个邮箱”做了对照——Go 的 channel 是**一等公民**，可以独立传递、组合，这是与 Actor 模型的关键差异。
- **《The Problem with Threads》（Edward A. Lee，IEEE Computer，2006）**：伯克利教授 Lee 的著名檄文，论证传统共享内存线程的“野性非确定性”如同当年的 goto，必须由更结构化的模型收编。这是对 Pike 立场最有力的学术背书。

## 四、批判性审查：哪些站得住，哪些要打折扣

**站得住的部分。**第一，概念区分本身早已是教科书共识（如 CS:APP、《Operating Systems: Three Easy Pieces》的并发章节都用类似框架），Pike 的贡献是用“结构 vs 执行”四个字把它变得可传授。第二，预言被后续十年验证：Trio 库提出的**结构化并发**（Martin Sústrik 2016 年提出概念、Nathaniel Smith 2018 年的长文使其流行）、Swift 5.5（2021）引入 async/await 与 Actor、Java 经 Project Loom 在 JDK 21（2023）交付虚拟线程、Kotlin 协程 2018 年稳定化——整个行业不约而同走向“轻量执行体 + 显式取消/作用域”，方向与这堂课一致。第三，工业战绩扎实：Docker、Kubernetes、etcd、Terraform 等基础设施全部构建在这套模型上。

**需要打折扣的部分。**其一，“并发让程序更易懂”是一个**有前提的设计主张，不是定律**。channel 并不自动消灭竞态——所有权纪律靠程序员自觉，编译器不强制；Go 官方在 2013 年前后就不得不内置竞态检测器（基于 ThreadSanitizer），恰恰说明“靠通信共享内存”仍会写出数据竞争。死锁和 goroutine 泄漏（忘记关闭的 channel 挂住执行体）是这套模型的专属新坑。其二，性能上存在被回避的代价：消息传递有序列化/调度开销，在超低延迟交易系统、DPDK 网络栈这类领域，无锁共享内存依然是王座。其三，加速比问题被轻描淡写：Amdahl 定律（1967）提醒你程序里串行部分是天花板；Gustafson（1988）虽然从“扩大问题规模”的视角给出更乐观的修正，但对“加了 goroutine 就快了”的民间误读，两条定律都是一盆冷水。其四，Go 自身花了八年才补齐模型的短板——直到 Go 1.14（2020）才有异步抢占，此前一个不含调度点的死循环 goroutine 可以饿死整个 P——说明“轻量执行体”的优雅之下是实实在在的运行时工程债务。

**一个公允的结论**：这堂课的立论在“概念辨析 + 结构主张”层面近乎无懈可击；它的乐观，只在其把工程代价说得过于轻巧时才需要警惕。

## 五、认知提升与实用启示

**启示一：用“单核检验法”审视你的设计。**写下任何并发代码前，先问一句：“如果只有一个核，这个结构还成立吗？”如果答案为否，说明你在用并发技巧掩盖设计问题；如果答案为是——任务边界清晰、数据所有权明确——那么并行收益只是时间问题。并发先服务可读性，再服务性能。

**启示二：把四个最小模式练进肌肉记忆。**管道（pipeline）、扇入/扇出、工作池（worker pool）、退出信号（done/cancel）。每个都能在二十行内手写实现，是这堂课动画背后的全部操作集。配上一条铁律：测试永远带 `-race` 跑，取消信号永远显式传递（Go 里即 context），不给“泄漏的 goroutine”留出生土壤。

**启示三：跨模型对照，破除“物理必然”错觉。**用 Elixir/Erlang 的邮箱模型、Rust 的所有权与异步运行时、或 Java 虚拟线程，重解同一个练习题（比如并发爬虫）。你会发现“并发长什么样”是语言的设计选择而非物理必然——这一步能把你从“某个框架的用户”提升为“并发模型的选择者”，这正是 Pike 这堂课真正想教的东西。

## 六、视频论证结构图

```mermaid
flowchart TD
    subgraph HW["硬件背景"]
        A["主频红利见顶<br/>登纳德缩放失效（2005年前后）"] --> B["多核与大规模并行硬件普及"]
    end
    subgraph CORE["Pike 的核心论证"]
        B --> C["并发 = 结构<br/>同时应对多件事"]
        B --> D["并行 = 执行<br/>同时做成多件事"]
        C --> E["两者正交：<br/>并发是设计，并行是执行"]
        D --> E
        E --> F["并发结构的价值独立于并行：<br/>清晰、响应性、与问题结构对齐"]
    end
    subgraph LINE["理论血脉"]
        G["Dijkstra 信号量（1965）"] --> H["Hoare CSP 论文（1978）"]
        H --> I["Occam / Transputer（1980年代）"]
        I --> J["Newsqueak / Alef / Limbo（贝尔实验室）"]
        J --> K["Go：goroutine + channel + select（2009）"]
    end
    F --> L["实践模式：<br/>管道 / 扇入扇出 / 负载均衡 / 退出信号"]
    K --> L
    L --> M["后续验证：结构化并发、Swift Actor、<br/>Kotlin 协程、Java 虚拟线程（2023）"]
    L --> N["代价与争议：<br/>竞态仍需检测器、死锁/泄漏新坑、消息传递开销"]
```

## 七、延伸阅读

1. C.A.R. Hoare《Communicating Sequential Processes》（CACM 1978）——这堂课全部思想的源头文本，配合 Wikipedia 的 CSP 词条入门更平滑。
2. Nathaniel Smith《Notes on structured concurrency, or: go statement considered harmful》（2018）——十年后对这堂课最精彩的一次“补丁与修正”。

## 参考来源

1. [Rob Pike：Concurrency Is Not Parallelism 演讲幻灯片（Go 官网托管）](https://go.dev/talks/2012/waza.slide) — 演讲原文与核心定义的权威版本；视频本体可在 YouTube 站内检索标题观看（Heroku 官方频道及会议方上传版本）。
3. [Herb Sutter：The Free Lunch Is Over](http://www.gotw.ca/publications/concurrency-ddj.htm) — 2005 年多核转折点的标志性文章。
4. [Nathaniel Smith：Notes on structured concurrency](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/) — 结构化并发对 Go 式并发的反思与修正。
5. [The Go Memory Model（官方文档）](https://go.dev/ref/mem) — 官方对竞态、同步与 channel 语义的严格定义，是“channel 不自动免疫竞态”的直接证据。

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID： gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
