在编程语言与系统设计领域,很少有概念像“并发”与“并行”这样频繁被混用,却又极其需要厘清。2012年,Go语言的创始人之一、Unix和C语言的先驱Rob Pike在Heroku Waza大会上发表了一场题为“Concurrency Is Not Parallelism”(并发不是并行)的演讲。这场时长约30分钟的视频,至今仍在技术社区被反复观看和引用,因为它用通俗易懂的比喻和清晰的代码示例,拆解了一个长期困扰开发者的核心认知误区。

演讲背景:Go语言与CSP模型

当时,Google推出的Go语言(2009年公开)正凭借其轻量级goroutine和channel设计吸引越来越多关注。Go的并发模型基于CSP(通信顺序进程),强调通过通信来共享内存,而非通过共享内存来通信。Rob Pike作为Go语言的核心设计者之一,发现很多初学者将goroutine的并发能力直接等同于并行计算,这催生了这场演讲的诞生。他希望通过这次分享,帮助开发者建立正确的设计思维——并发是一种结构化的编程方式,而并行是执行阶段的一种优化手段。

核心观点:并发是“处理”,并行是“执行”

演讲中,Pike用一个极其经典的比喻开场:想象你在做咖啡和烤面包。如果你有一台咖啡机和一个烤面包机,你可以先启动咖啡机,在等待咖啡煮好的同时去烤面包——这是并发(composition of independently executing processes)。而如果你有两台咖啡机和两个烤面包机同时工作,那就是并行(simultaneous execution)。但关键点在于:并发让你能够设计出更清晰、更易扩展的程序结构,而并行只是硬件加速的结果。

Pike进一步用代码演示了Go语言中如何通过goroutine和channel实现并发设计。他展示了一个“暴风雪搜索”的例子:多个搜索函数同时运行,通过channel汇聚结果。他强调,这种设计将问题分解为独立的任务(并发),而是否真正并行执行取决于底层硬件(例如单核CPU上goroutine是并发切换,多核才可能并行)。开发者应该首先关注并发结构,它决定了程序的健壮性、可读性和可组合性;并行则是在结构之上自然获得的性能红利。

为什么这个观点至今重要?

十多年过去,云计算、微服务、大语言模型推理等场景对并发处理的需求只增不减。不少开发者仍在错误地将“并行”作为设计目标:为了用满CPU核心,强行将任务拆成固定数量的线程,却忽略了任务之间的依赖和通信成本,导致代码难以维护、死锁频发。Pike的演讲像一剂清醒剂:并发是关于如何编写程序以处理多个事情,并行是关于如何利用硬件加速这些事情。 一个糟糕的并发设计,即使运行在128核服务器上,也可能比一个精心设计的单线程程序更慢。

此外,这场演讲也影响了后来许多语言和框架的并发哲学。例如,Rust的async/await机制、Elixir的Actor模型、Java的虚拟线程(Project Loom),都在不同程度上吸收了“并发作为设计原则”的思想。Go语言本身的goroutine调度器,就是“并发非并行”理念的工程落地——用户只需用go关键字启动任务,调度器会自动在少量系统线程上分配这些任务,实现高效的并发执行。

视频亮点与观看方式

该演讲视频目前可在YouTube(Google TechTalks频道)上免费观看,配有中文字幕。视频中,Pike用幽默的语调和生动的板书(纸质幻灯片)让抽象概念变得直观。例如,他手绘了“火人节”的停车场示意图,说明多个异步任务如何避免冲突。他还专门强调了“并行主义”(parallelism)不是银弹,“如果你在并发设计上偷懒,并行只会让问题更糟”

结语:一场演讲,一次思维转变

对于正在学习Go语言或任何涉及多任务处理技术的开发者,重看这场2012年的视频仍然极具价值。它提醒我们:不要被硬件性能的增长迷惑,真正的工程智慧在于设计出可分解、可组合的并发系统。Rob Pike用30分钟证明了一个朴素但深刻的道理:并发是程序员的责任,并行是硬件的礼物。理解二者的区别,不仅是技术能力的提升,更是设计思维的成熟。

(全文约980字)