Go 语言原本 under the hood
Go 语言原本

第 10 章 通道与 select

本章配有一个线上演讲:YouTube 在线Google Slides 讲稿

「不要以共享内存的方式通信,而要以通信的方式共享内存。」这句广为流传的格言,是 Go 并发哲学的 浓缩。channel 正是这句话的载体,它把同步与数据传递合二为一。CSP 的思想渊源已在 1.3 顺序进程通讯 交代,本章不再重复,而是聚焦于 channel 与 select 在运行时里究竟如何实现:一个 channel 在内存里长什么样、一次收发如何在两个 goroutine 间会合、关闭如何广播、select 如何在多路通信间公平而无死锁地择一,以及这套机制 为何选择有锁、又如何与内存模型咬合。

通道用以编排,互斥锁用以串行。
Channels orchestrate; mutexes serialize.
-- Rob Pike, "Go Proverbs", Gopherfest SV 2015

这句格言点出了 channel 在 Go 并发里的定位:它不是又一把锁,而是一种编排手段,把若干 goroutine 之间「谁在何时与谁交换什么」组织成可读的结构。耐人寻味的是,运行时把这层编排语义兑现的方式, 偏偏正是格言另一端的那把互斥锁。本章会一路追到这处张力的尽头,看清「以通信编排」的抽象, 最终如何落在「以锁串行」的实现之上。