现在我们都说设计可并行的程序、高并发的程序?而且很多时候潜意识里面觉得对并行(Parallelism)和并发(Concurrency)的的区别很清楚,但是如果要明确的说出二者的区别,又感觉没法给出一个非常清晰的描述。最近看到Go语言发明者之一Rob Pike的一篇演讲《Concurrency is not Parallelism》,觉得挺不错的。因为特别喜欢的里面的配图示例,所以我决定写本篇博客,将其转过来,也方便一些网络不畅的人。下面给出原文涉及的一些链接:

演讲幻灯片请移步:https://talks.golang.org/2012/waza.slide
演讲视频请移步:https://www.youtube.com/watch?v=cN_DpYBzKso&t=550s

那什么是并发?什么又是并行呢?并行的概念比较简单,并行总是和执行(executions)相关,很多东西同时执行就是并行;而并发则是通过一些方式组织你的程序,让它可以分成多个模块去独立的执行。并行必然是需要多核的,一个处理器是无法并行的;但并发和处理器并没有什么必然联系,在一个处理器上面,我们的程序也可以是并发的。好吧,有点绕。我们直接上Rob Pike的例子:这个例子是gopher们需要将一堆过时的语言指导书用小推车推到垃圾焚烧炉去烧毁(这个例子也是非常搞笑...)。

刚开始,我们只有一个gopher,完成任务必然需要比较长的时间:

gophersimple1.jpg

此时,如果再增加一个gopher,那也没用,因为它没有车...

gophersimple3.jpg

好吧,那我们再找辆车:

gophersimple2.jpg

这样虽然比之前快了,但还是有瓶颈的。因为书只有一堆,火炉也只有一个,所以我们还必须通过消息来协调两个gopher的行动。好吧,那我们再把书分成两堆,再增加一个火炉:

gophersimple4.jpg

这样就OK了,我们就可以比之前快差不多一倍了。

这个模型就是并发的,因为两个gopher可以独立的完成一件事了;但是却不一定是并行的,比如可能同一时刻只有一个gopher是干活的。但是我们这样去组织的话,让程序并行执行也会非常的容易。当然,除了这种,我们还可以设计出来很多并发模型,继续接着看漫画...

这次我们找了3个gopher,一个专门负责装车,一个专门负责运输,一个专门负责卸货焚烧,当然三个gopher之间需要使用一些诸如消息通信之类的手段进行协调。

gophercomplex0.jpg

然而我们却发现运输的这个gopher很累,有瓶颈。好,我们再招聘一个gopher,专门负责还空车:

gophercomplex1.jpg

两个gopher去搞运输,这样如果协调的好的话,理论情况下工作效率将是一个gopher的4倍。

这个新的并发模型就会比之前的模型更高级一点了,此时我们再将这种并发模型并行化:

gophercomplex2.jpg

漫画还没完,我们接着看另外一种并发模型:

运输的gopher抱怨说运输路程太远,那我们就增加一个中转站(我觉得实际中这个gopher很可能会被解雇):

gophercomplex3.jpg

然后再将这种并发模型并行化:

gophercomplex4.jpg

我们也可以这样设计并发模型:

gophercomplex5.jpg

然后再并行化:

请输入图片描述

OK,至此漫画就完了。可以看到有很多种并发模型,每种模型也可以很容易的并行化起来。回到程序中,书就代表着数据;gopher就是CPU;而车可能就是一些序列化、反序列化、网络等设施;火炉就是代理、浏览器或者其他的消费者。而上面的并发模型就是一个可扩展的Web Service。

至此,我们对于并发和并行的关系应该比较清楚了。最后再引用一些描述:

Concurrency is about dealing with lots of things at once.
Parallelism is about doing lots of things at once.
Not the same, but related.
Concurrency is about structure, parallelism is about execution.
Concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable.
Parallelism is simply running things in parallel.
Concurrency is a way to structure your program.

如果喜欢看图的,这里再推荐一篇2016年Gopher大会上的一个演讲的文章:Visualizing Concurrency in Go,里面的配图也非常的炫酷哦~