并发和并行之间的区别是什么?


当前回答

在我看来,理解这两者最简单、最优雅的方式是这样的。并发允许交错执行,因此会产生并行的错觉。例如,这意味着并发系统可以在您用Word编写文档的同时运行Youtube视频。底层操作系统是一个并发系统,使这些任务能够交错执行。由于计算机执行指令的速度如此之快,这就给人一种同时做两件事的感觉。

平行性是指这样的事情实际上是平行的。在上面的示例中,您可能会发现视频处理代码在一个内核上执行,而Word应用程序在另一个内核中运行。注意,这意味着并发程序也可以并行!使用线程和进程构建应用程序,使程序能够利用底层硬件,并可能并行完成。

那为什么不让一切都平行呢?一个原因是因为并发是一种结构化程序的方式,是一种促进关注点分离的设计决策,而并行常常以性能的名义使用。另一个问题是,有些事情根本上无法完全并行完成。这方面的一个例子是在队列的后面添加两件事——不能同时插入这两件事。一定要有东西在前面,另一个在后面,否则你会把队伍弄得一团糟。虽然我们可以交错这种执行(因此我们得到了一个并发队列),但不能让它并行。

希望这有帮助!

其他回答

要补充其他人所说的话:

并发性就像让一个玩杂耍的人玩多个球。不管看起来如何,玩杂耍的人每次只手抓/扔一个球。平行运动是让多个杂耍者同时变戏法。

在电子学中,串行和并行表示一种静态拓扑,决定电路的实际行为。当没有并发时,并行性是确定性的。

为了描述动态的、与时间相关的现象,我们使用了术语顺序和并发。例如,可以通过特定的任务序列(例如配方)获得特定的结果。当我们与某人交谈时,我们会产生一系列单词。然而,在现实中,许多其他过程在同一时刻发生,因此,与某一行动的实际结果一致。如果很多人在同一时间谈话,同时进行的谈话可能会干扰我们的顺序,但这种干扰的结果事先不知道。并发性引入了不确定性。

串行/并行和顺序/并行表征是正交的。数字通信就是一个例子。在串行适配器中,数字消息沿同一通信线路(例如,一根电线)临时(即顺序)分布。在并行适配器中,这也在并行通信线路(例如多条电线)上进行划分,然后在接收端进行重构。

让我们想象一个有9个孩子的游戏。如果我们将它们作为一条链处理,在开始时发送消息,在结束时接收消息,我们将进行串行通信。更多的单词组成了一系列的交流单元。

I like ice-cream so much. > X > X > X > X > X > X > X > X > X > ....

这是在串行基础结构上复制的顺序过程。

现在,让我们想象一下,把孩子们分成三组。我们把这个短语分成三部分,第一部分给左边的孩子,第二部分给中心线的孩子,等等。

I like ice-cream so much. > I like    > X > X > X > .... > ....
                          > ice-cream > X > X > X > ....
                          > so much   > X > X > X > ....

这是一个在并行基础结构上复制的顺序过程(尽管仍部分序列化)。

在这两种情况下,假设孩子之间有完美的沟通,结果会提前确定。

如果有其他人与您同时与第一个孩子交谈,那么我们将同时进行处理。我们不知道基础设施将考虑哪个过程,因此最终结果尚未提前确定。

同意:具有共享资源潜力的多个执行流

前任:两个线程竞争I/O端口。

视差:将问题分成多个相似的块。

前任:通过对文件的每一半运行两个进程来解析大文件。

并发简单意味着多个任务正在运行(不需要并行)。例如,假设我们在任何时刻都有3个任务:多个任务可能正在运行,或者所有任务可能同时运行。

并行性意味着它们实际上是并行运行的。因此,在这种情况下,三者必须同时运行。

派克的“并发”概念是一个有意的设计和实现决策。具有并发能力的程序设计可能表现出行为上的“并行性”;这取决于运行时环境。

你不希望一个不是为并发而设计的程序表现出并行性。:-)但就相关因素(功耗、性能等)而言,这是一个净收益,您需要最大程度的并发设计,以便主机系统可以在可能的情况下并行执行。

派克的Go编程语言将这一点发挥到了极致:他的函数都是可以同时正确运行的线程,也就是说,如果系统有能力,调用函数总是会创建一个与调用者并行运行的线程。一个拥有数百甚至数千个线程的应用程序在他的世界中是非常普通的。(我不是围棋专家,这只是我的看法。)