并发与并行

concurrency vs parallelism

并发指的是程序的结构,并行指的是程序运行时的状态。

所谓并行,就是同时执行的意思。判断程序是否处于并行的状态,就看同一时刻是否有超过一个“工作单位”在运行就好了。所以,单线程永远无法达到并行状态

要理解“并发”这个概念,必须得清楚,并发指的是程序的“结构”。当我们说这个程序是并发的,实际上,这句话应当表述成“这个程序采用了支持并发的设计”。既然并发指的是人为设计的结构,那么怎样的程序结构才叫做支持并发的设计?

并发设计的标准:使多个操作可以在重叠的时间段内进行(two tasks can start, run, and complete in overlapping time periods)。

这句话的重点有两个。我们先看“操作在重叠的时间段内进行”这个概念。它是否就是我们前面说到的并行呢?是,也不是。并行,当然是在重叠的时间段内执行,但是另外一种执行模式,也属于在重叠时间段内进行。

下面看并发程序处理的时序图:

task1, task2 是两段不同的代码,比如两个函数,其中黑色块代表某段代码正在执行。注意,这里从始至终,在任何一个时间点上都只有一段代码在执行,但是,由于 task1 和 task2 在重叠的时间段内执行,所以这是一个支持并发的设计。与并行不同,单核单线程能支持并发。

那么并发与并行两者之间有何关系?

Different concurrent designs enable different ways to parallelize.

这句话引用自: Concurrency is not parallelism 。用自己的话总结来说就是:并发设计让并发执行成为可能,而并行是并发执行的一种模式

到这里很多人会觉得,并行其实是并发的子集,这句话可对可不对,因为必须站在不同的角度来理解。实际上如果仅限于 Task-Level 这一层,在这一层上,并行无疑是并发的一个子集。

但是并行并非并发的子集,计算机在不同层次上都使用了并行技术,比如在 Bit-Level 和 Instruction-Level (指令集并行)上的并行不属于并发。具体可以参考《七周七并发模型》里面有提到。

所以,正确的说法是这样:并行指物理上同时执行,并发指能够让多个任务在逻辑上交织执行的程序设计

按照现在的理解,并发针对的是 Task-Level 及更高层,并行则不限。这也是它们的区别。