并发VS并行 – 有什么区别?

并发VS并行 – 有什么区别? 任何例子

并发性是两个或多个任务可以在重叠的时间段内启动,运行并完成的时间。 这并不一定意味着他们将在同一时刻同时运行。 例如。 在单核机器上执行多任务。

并行是当任务在同一时间运行,例如。 在多核处理器上。

引用Sun的multithreading编程指南

  • 并发性:至less有两个线程正在进行时存在的条件。 一种更普遍的并行性forms,可以包括时间分割作为虚拟并行的一种forms。

  • 并行性:至less有两个线程同时执行时出现的情况。

我喜欢Rob Pike的话:并发不是并行(更好!) (幻灯片) (说)

Rob通常会谈论Go,通常以直观和直观的解释来解决并发VS并行的问题! 这里是一个简短的总结:

任务:让我们烧掉一堆陈旧的语言手册! 一次一个!

任务

并发性:有很多并发的任务分解! 一个例子:

地鼠

并行性:如果至less有两个Gopher在同一时间工作,则以前的configuration并行发生。

存在混淆因为这两个词的字典含义几乎相同:

  • 并发同时存在,发生或完成(dictionary.com)
  • 平行 :非常相似,经常同时发生(merriam webster)。

然而,他们在计算机科学和编程中使用的方式却完全不同。 这是我的解释:

  • 并发性 :可中断性
  • 并行性 :独立性

那么上面的定义是什么意思? 我将用现实世界的比喻来澄清。 假设你必须在一天内完成两项非常重要的任务

  1. 得到护照
  2. 完成一个演示

现在问题是任务1需要你去一个非常官僚的政府办公室,让你排队等待4个小时拿到你的护照。 而任务2需要在你的办公室完成,而且是至关重要的。 这两个都必须在特定的一天完成。

案例1:顺序执行通常情况下,你将开车到护照办公室2小时,排队等待4小时,完成任务,开车回来两个小时,回家,再离开5个小时,完成演示。

案例2:并发执行:但你很聪明。 你提前计划。 你所做的是,你随身携带一台笔记本电脑,在等待排队时,你开始处理你的演示文稿。 这样,一旦你回到家里,你只需要加class一小时,而不是再加五个小时。 在这种情况下,这两项任务都是由你完成的,只是件数。 你在排队等候的时候打断了护照任务,并进行了演示。 而当你的号码被叫,你中断演示任务,并切换到护照任务。 由于这两项任务的可中断性,节省时间本质上是可能的。 在数据库的ACID属性中,并发性应视为“隔离”。如果以任何交叉方式执行每个子事务,并且最终结果与两个任务是串行完成的相同,则两个数据库事务满足隔离要求。 请记住,对于护照和演示任务,你是唯一的execution子手。

案例3:平行执行现在,因为你是一个聪明的家伙,显然你是一个更高层,你有一个助手。 现在在你离开护照任务之前,你打电话给他,并告诉他准备介绍的初稿。 你花了一整天的时间完成护照任务,回来看看你的邮件,你会发现演示稿。 他做了一个非常稳定的工作,并在2个小时内进行了一些编辑,最后确定。 现在,你的助手和你一样聪明,他可以独立工作,而不需要你经常澄清。 因此,由于任务的独立性,他们同时由两名不同的execution子手执行。

还跟我? 好的 ..

案例4:同时但不是平行记住你的护照任务,你必须排队等候吗? 在这种情况下,请注意,由于这是您的护照,您的助手不能排队等候。 因此,护照任务具有中断能力(你可以在排队等待时停下来,稍后当你的号码被呼叫时恢复),但没有可以独立的(你的助手不能等着你)。

案例5:平行而不是并行说政府办公室有安全检查进入房屋。 在这里,你必须取下所有的电子设备,并提交给你只有完成你的任务后才能回来的军官。 在这种情况下,护照任务既不独立也不可中断。 即使你排队等候,你也不能在别的地方工作,因为你没有必要的设备。 同样,如果说演示文稿的math性质非常高,那么至less需要5个小时才能达到100%的浓度。 即使您携带笔记本电脑,也无法在等待护照任务时执行此操作。 在这种情况下,演示任务是独立的(无论是你还是你的助手都可以投入5个小时的精力),但不能中断。

案例6:并行和并行执行现在说除了给演示文稿分配一个助理之外,你还携带一台笔记本电脑与你一起护照任务。 在排队等候的时候,你看到助理已经在共享卡组里创build了前10张幻灯片。 你发表意见给他,纠正他。 因此,现在当你回家的时候,你只需要15分钟,而不是花2个小时来完成选秀。 这是可能的,因为演示任务具有可独立性(你们中的任何一个都可以做到)和可中断性(可以停止并稍后恢复)。 所以你同时执行任务和只执行演示任务并行。

可以这么说,政府办公室是腐败的,除了过于官僚。 这样,你可以input密码,显示你的身份certificate,开始排队等候你的号码,给警卫一些钱,让其他人守住你的位置,溜出去,在你的号码被叫之前回来,恢复它。

在这种情况下,您可以同时并行执行护照和演示任务。 你可以偷偷摸摸,你的位置由你的助手。 你们两个都可以在演讲中工作

回到计算机科学:在计算世界中,经常看到情况1,例如中断处理。

情况-2只有一个处理器,但所有正在执行的任务由于I / O而有等待时间。

我们在讨论map-reduce或hadoop集群时经常会看到case-3。

我认为情况4是罕见的,很less发生一个任务是并行的,但不是并行的。 但是这可能是因为你的任务需要访问一个特殊的计算芯片,只能通过处理器1访问。 因此,即使处理器-2空闲且处理器-1正在执行某个其他任务,特殊计算任务也不能在处理器-2上进行。

案例5也很less见,但并不像案例4那样罕见。 非并发代码可以是受互斥体保护的关键区域。 一旦启动,它必须完全执行。 但是,两个不同的关键区域可以在两个不同的处理器上同时进行

案例-6:IMO,大多数时候我们谈论的是并行或并发编程,我们基本上是在谈论最后一个并行和并发执行混合匹配的情况6。

并发性和Go:如果你看到Rob Pike为什么说并发性更好,你必须明白,原因是,你有一个非常长的任务,在这个任务中有多个等待期间,你等待一些外部操作,如文件读取,networking下载。 在他的演讲中,他所说的只是打破这个漫长的顺序任务,让你在等待的时候做一些有用的事情。 这就是为什么他会与各种地鼠讨论不同的组织。 现在,Go的优势来自于通过“go”关键字和频道使得这一切变得非常简单。 在运行时也有很好的基础支持来安排这些goroutines。

但从本质上讲,并行性是否更好?

苹果比橘子更受欢迎吗?

增加别人的话:

并发就像有一个玩杂耍的人玩转很多球。 不pipe看起来如何,这个玩杂耍的人每次只能每手抓一个球。 平行主义正在让多个玩杂耍的人同时玩弄球。

假设你有一个有两个线程的程序。 该程序可以运行在两个方面:

Concurrency Concurrency + parallelism ___ ___ ___ |th1| |th1|th2| | | | |___| |___|___ | |___ |th2| |___|th2| ___|___| ___|___| |th1| |th1| |___|___ | |___ |th2| | |th2| 

在这两种情况下,我们都有一个事实就是并发,即我们有多个线程在运行。

如果我们在一个CPU核心的计算机上运行这个程序,操作系统将在两个线程之间切换,从而允许一次运行一个线程。

如果我们在有多核CPU的计算机上运行这个程序,那么我们就可以并行运行这两个线程 – 并排运行。

并发性:如果一个处理器解决了两个或多个问题。 替代文字

并行性:如果一个问题被多个处理器解决。

替代文字

具有共享资源潜力的多个执行stream程

例如:两个线程竞争一个I / O端口。

平等主义:以多个相似的块分裂问题。

例如:通过在文件的每一半上运行两个进程来parsing一个大文件。

我将尝试用一个有趣而易于理解的例子来解释。 🙂

假设一个组织一个国际象棋比赛,其中有10名棋手( 具有相同的象棋技巧 )将挑战一名职业冠军棋手。 由于国际象棋是1比1的比赛,因此组织者必须及时有效地进行10场比赛,以便尽快完成整个赛事。

希望下面的情景可以很容易地描述进行这10场比赛的多种方式:

1)SERIAL – 让专业人员逐一跟每个人玩,即开始和完成一个人的游戏,然后与下一个人开始下一个游戏,等等。 换句话说,他们决定继续进行游戏。 因此,如果一场比赛需要10分钟才能完成,那么10场比赛将需要100分钟,也假定从一场比赛转换到另一场比赛需要6秒,然后10场比赛将是54秒(大约1分钟)。

所以整个活动将在101分钟左右完成( 最差的方法

2)CONCURRENT (并行 – 让专业人员轮stream转到下一个玩家,这样所有10个玩家同时在玩,但是职业玩家一次不会与两个人玩,他轮到他下一个人。 现在假设职业玩家需要6秒的时间来轮到他们,同时职业玩家的转场时间是两秒,所以总回合时间是1分钟(10×6秒)。 因此,当他回到第一人的时候,比赛已经开始了,2分钟已经过去了(10xtime_per_turn_by_champion + 10xtransition_time = 2分钟)

假设所有玩家都需要45秒才能完成他们的回合,所以根据SERIAL赛事的每场10分钟, 在比赛结束之前轮数应该是600 /(45 + 6)= 11轮(大约)

所以整个事件大概在11xtime_per_turn_by_player _&_ champion + 11xtransition_time_across_10_players = 11×51 + 11x60sec = 561 + 660 = 1221sec = 20.35mins(大约)

从101分钟改善到20.35分钟( 更好的方法

3)PARALLEL – 让组织者得到一些额外的资金,因此决定邀请两个职业冠军球员 (都是同样的能力),并分成两组,每组5人,分成两组,每组两人,分组。 现在这两项赛事同时进行,即至less有两名选手(每组一名)与两名职业选​​手对阵。

然而在小组内职业选手一次只能拿到一名选手,所以没有任何计算,你可以很容易地推断出整个比赛将在101/2 = 50.5分钟内完成

从101分钟改善到50.5分钟( 良好的方法

4)并发+并行 – 在上面的情况下,可以说两个冠军玩家将与他们各自的队伍中的5个玩家同时玩(读第二点),所以现在跨组的游戏并行运行,但是在同一队内运行。

因此,一组中的游戏将在11xtime_per_turn_by_player _&_champion + 11xtransition_time_across_5_players = 11×51 + 11×30 = 600 + 330 = 930sec = 15.5mins(大约)

所以整个事件(涉及两个并行运行组)将在15.5分钟左右完成

从101分钟改善到15.5分钟( 最佳方法

注意:在上述情况下,如果用10个相似的作业replace10个播放器,并且用两个CPU核心replace两个专业播放器,则下列顺序将保持为真:

串行>并行>并发>并发+并行

(注意:这个顺序可能会改变其他情况,因为这个顺序很大程度上取决于作业的相互依赖性,通信需求b / w作业和转换开销b / w作业)

他们解决不同的问题。 并发解决了CPU资源不足和许多任务的问题。 因此,您通过代码创build线程或独立的执行path,以便在稀缺资源上共享时间。 直到最近,由于CPU的可用性,并发已经主导了讨论。

并行性解决了find足够的任务和适当的任务(可以正确拆分的任务)并将它们分配到丰富的CPU资源上的问题。 并行性一直是当然的,但是由于多核处理器价格便宜,所以它已经走到了前列。

简单的例子:

同时是:“两个队列访问一台ATM机”

并行是:“两排队和两台ATM机”

把它看作服务队列,服务器只能在队列中服务第一个工作。

1个服务器,1个作业队列(有5个作业) – >没有并发,没有并行性(只有一个作业正在服务完成,队列中的下一个作业必须等待,直到服务的作业完成,没有其他服务器服务)

1个服务器,2个或更多不同的队列(每个队列有5个作业) – >并发(因为服务器与队列中的所有第一个作业共享时间,平均或加权),仍然没有并行性,因为在任何时刻,工作正在服务。

2个或更多的服务器,一个队列 – >并行(在同一时刻完成2个工作),但没有并发(服务器不共享时间,第三个工作必须等到一个服务器完成。

2个或更多的服务器,2个或更多不同的队列 – >并发和并行

换句话说,并发性是共享时间来完成一项工作,它可能会占用同一时间来完成它的工作,但至less它可以提前开始。 重要的是,工作可以分成更小的工作,这可以交错。

并行性是通过并行运行更多的CPU,服务器和人员来实现的。

请记住,如果资源是共享的,纯并行是不可能实现的,但是这就是并发性最适合实际使用的地方,占用不需要资源的另一项工作。

并发性 =>当多个任务与共享资源同时执行时。

并行 =>当单个任务分成多个简单的独立任务可以同时执行。

想象一下通过观看video教程学习一种新的编程语言。 您需要暂停video,应用代码中所说的内容,然后继续观看。 这是并发性。

现在你是一个专业程序员。 而编码时,你喜欢听冷静的音乐。 这是并行的。

请享用。

我打算提供一个与这里的一些stream行答案相矛盾的答案。 在我看来,并发是一个包含并行的总称。 并发适用于任何不同的任务或工作单元在时间上重叠的情况。 并行性更具体地适用于在同一物理时间评估/执行不同工作单元的情况。 并行性的存在正在加速可以从多个物理计算资源中受益的软件。 适合并发的另一个主要概念是交互性。 交互性适用于任务重叠可从外部世界观察到的情况。 交互性的存在正在使软件能够响应用户,networking对等设备,硬件外设等真实世界的实体。

并行性和交互性几乎完全是并发性的独立维度。 对于一个特定的项目开发人员可能关心,两者兼而有之。 他们倾向于混淆,尤其是因为线程的憎恶给了一个合理的方便的原始做两个。

有关并行性的更多细节

并行性存在于非常小规模(例如处理器中的指令级并行),中等规模(例如多核处理器)和大规模(例如高性能计算集群)中。 由于多核处理器的增长,近年来软件开发人员面临更multithreading级并行的压力增加。 并行性与依赖的概念密切相关 。 依赖限制了并行性可以达到的程度; 两个任务不能并行执行,如果依赖另一个(忽略猜测)。

有许多程序员用来expression并行性的模式和框架:stream水线,任务池,数据结构的集合操作(​​“并行数组”)。

关于交互性的更多细节

做交互的最基本和常见的方式是事件(即事件循环和处理程序/callback)。 对于简单的任务事件是伟大的。 试图用事件做更复杂的任务进入堆栈翻录(aka callback hell; aka control inversion)。 当你厌倦了事件,你可以尝试更奇特的东西,如发电机,协同程序(又名Async / Await),或合作的线程。

对于可靠的软件的爱,请不要使用线程,如果你想要的是交互性。

Curmudgeonliness

我不喜欢Rob Pike的“并发不是并行,更好”的口号。 并发性既不比并行性好也不差。 并发性包括交互性,这种交互性不能以更好/更差的方式与并行性进行比较。 这就像是说“控制stream程比数据更好”。

并发是并行的一般化forms。 例如并行程序也可以被称为并发,但是反向并不正确。

  1. 并行执行可能在单处理器(multithreading,由调度程序或线程池pipe理)

  2. 并行执行不可能在单个处理器上,而是在多个处理器上。 (每个处理器一个进程)

  3. 分布式计算也是一个相关的主题,它也可以被称为并行计算,但是反向并不是真实的,就像并行。

有关详细信息,请阅读本研究论文“并行编程概念”

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

为了描述dynamic的, 与时间相关的现象 ,我们使用顺序并发的术语。 例如,可以通过一定的任务序列 (例如配方)获得某个结果。 当我们和某人交谈时,我们正在产生一系列的话语。 但实际上,其他很多过程同时发生,因此也同意某一行为的实际结果。 如果很多人同时在说话,同时谈话可能会干扰我们的顺序,但这种干扰的结果是不可预知的。 并发性引入了不确定性

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

让我们想像一个有9个孩子的游戏。 如果我们把它们作为一个链条来处理,首先给出一个消息,然后在最后接收它,我们将会有一个串行通信。 更多的话语组成了信息,包括一系列的交stream团体。

 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 > .... 

这是一个在并行基础架构上再现的连续过程 (尽pipe如此,仍然是部分序列化的)。

在这两种情况下,假设孩子之间有一个完美的交stream,结果是事先确定的。

如果有其他人与您同时与第一个孩子交谈,那么我们将同时进行处理 。 我们不知道基础设施将考虑哪个stream程,所以最终的结果是事先没有确定的。

并行性:有多个线程在数据和资源方面执行相互独立的类似任务,他们需要这样做。 例如:Google抓取工具可以产生数千个线程,每个线程都可以独立执行任务。

并发性:当共享数据,线程之间的共享资源时,并发性就出现了。 在一个事务处理系统中,这意味着你必须使用诸如锁,信号等一些技术来同步代码的关键部分。

太好了,让我来看看我的理解。 假设有3个孩子叫:A,B,C,A和B说话,C听。 对于A和B,它们是平行的:A:我是A. B:我是B.

但对C而言,他的大脑必须采取并发的过程来听A和B,可能是:我是IA和B.

我真的很喜欢Paul Butcher对这个问题的回答 (他是七个七个并发模型的作者):

虽然他们经常感到困惑,但并行和并发是不同的事情。 并发是问题领域的一个方面 – 您的代码需要处理多个同时(或几乎同时)的事件相反,并行是解决scheme领域的一个方面,您希望通过并行处理问题的不同部分使程序更快运行。 一些方法适用于并发性,一些适用于并行性,另一些适用于两者。 了解你所面临的问题,select合适的工具。

并发性可以涉及同时运行的任务(它们确实可以在单独的处理器/内核中运行,但是它们也可以在“ticks”中运行)。 重要的是并发性总是指做一件更大的任务 。 所以基本上它是一些计算的一部分。 你必须明白你可以同时做什么,不要做什么和如何同步。

并行性意味着你只是在同时做一些事情。 他们不需要成为解决一个问题的一部分。 例如,你的线程可以解决一个单一的问题。 当然,同步的东西也适用,但从不同的angular度来看。

并行编程涉及似乎重叠的操作,主要涉及由于非确定性控制stream而产生的复杂性。 与并发程序相关的定量成本通常是吞吐量和延迟。 并发程序往往是IO界限,但并不总是如此,例如并发垃圾收集器完全在CPU上。 一个并发程序的教学例子是一个networking爬虫。 该程序启动对网页的请求,并在下载结果可用时同时接受响应,累积一组已经访问过的页面。 控制stream是非确定性的,因为每次程序运行时,响应不一定以相同的顺序接收。 这个特性使得debugging并发程序非常困难。 某些应用程序基本上是并发的,例如Web服务器必须同时处理客户端连接。 Erlang也许是高度并发编程最有希望的语言。

并行编程涉及为了提高吞吐量的具体目标而重叠的操作。 并发编程的困难是通过使控制stream确定性来避开的。 通常,程序产生并行运行的子任务集合,并且只有每个子任务完成后,父任务才会继续。 这使并行程序更容易debugging。 并行编程的难点在于对​​粒度和通信等问题的性能优化。 后者在多核环境中仍然是一个问题,因为将数据从一个caching转移到另一个caching需要相当大的成本。 密集matrix乘法是并行编程的教学实例,可以通过Straasen的分治algorithm并行攻击子问题得到解决。 Cilk可能是在共享内存计算机(包括多核)上进行高性能并行编程的最有前途的语言。

并发性是独立执行的进程的组成,而并行是同时执行(可能相关)的计算。

并发是一次处理很多事情。 并行是一次做很多事情。

并发简单意味着多个任务正在运行(不必并行)。 例如,我们有3个任务,然后在任何时候:可能有多个人在跑,或者所有人都可能在同一时间跑。

并行性意味着它们正在平行运行。 那么在这种情况下,所有三个必须同时运行。

派克关于“并发”的概念是有意devise和实现的决定。 并发能力的程序devise可能会或可能不会performance出行为“并行性”; 它取决于运行时环境。

您不希望并行性不是为并发而devise的。 :-)但是,就相关因素(功耗,性能等)而言,这是一个净增益,您需要一个最大并行devise,以便主机系统在可能的情况下并行执行。

Pike's Go编程语言在极端情况下说明了这一点:他的函数是所有可以同时正确运行的线程,即调用一个函数总是创build一个与调用者并行运行的线程(如果系统有能力的话)。 拥有数百甚至上千个线程的应用程序在他的世界中是非常普通的。 (我不是专家,这只是我的承担。)

来自jenkov的java并发教程 :

术语并发性和并行性经常用于multithreading程序。 但是并发性和并行性究竟意味着什么,它们是相同的术语还是什么?

简短的回答是“不”。 虽然它们表面上看起来很相似,但它们并不相同。 我花了一些时间才最终find并理解并发和并行的区别。 因此,我决定在这个Java并发教程中添加一个关于并发性和并行性的文本。 并发

并发意味着应用程序正在同时(同时)在多个任务上取得进展。 那么,如果计算机只有一个CPU,则应用程序可能无法在同一时间完成多个任务,但应用程序内一次处理多个任务。 在下一个任务开始之前,它并没有完成一项任务。 排比

并行性意味着应用程序将其任务分解为可以并行处理的较小子任务,例如在同一时间在多个CPU上进行处理。 并发与并行性的细节

如您所见,并发与应用程序处理多个任务的方式有关。 应用程序可以同时处理一个任务(按顺序)或同时处理多个任务(同时)。

另一方面,并​​行性与应用程序如何处理每个单独的任务有关。 应用程序可以从头到尾地串行处理任务,或者将任务分成可以并行完成的子任务。

正如你所看到的,一个应用程序可以是并发的,但不是并行的。 这意味着它可以同时处理多个任务,但这些任务不会被分解为子任务。

应用程序也可以是并行的,但不是并行的。 这意味着应用程序一次只能处理一个任务,而这个任务被分解成可以并行处理的子任务。

另外,应用程序既不能并行也不能并行。 这意味着它一次只能处理一个任务,并且任务不会被分解为并行执行的子任务。

最后,应用程序也可以是并行的,也可以是并行的,因为它们既可以同时在多个任务上工作,也可以将每个任务分解为子任务以便并行执行。 但是,在这种情况下,并发性和并行性的一些好处可能会丢失,因为计算机中的CPU已经保持合理的忙于并发或并行。 把它结合起来可能只会带来很小的性能提升甚至性能损失。 确保在盲目采用并行模型之前进行分析和测量。

这个来源的解释对我有帮助:

并发性与应用程序处理多个任务的方式有关。 应用程序可以同时处理一个任务(按顺序)或同时处理多个任务(同时)。

另一方面,并​​行性与应用程序如何处理每个单独的任务有关。 应用程序可以从头到尾地串行处理任务,或者将任务分成可以并行完成的子任务。

正如你所看到的,一个应用程序可以是并发的,但不是并行的。 这意味着它可以同时处理多个任务,但这些任务不会被分解为子任务。

应用程序也可以是并行的,但不是并行的。 这意味着应用程序一次只能处理一个任务,而这个任务被分解成可以并行处理的子任务。

另外,应用程序既不能并行也不能并行。 这意味着它一次只能处理一个任务,并且任务不会被分解为并行执行的子任务。

最后,应用程序也可以是并行的,也可以是并行的,因为它们既可以同时在多个任务上工作,也可以将每个任务分解为子任务以便并行执行。 但是,在这种情况下,并发性和并行性的一些好处可能会丢失,因为计算机中的CPU已经保持合理的忙于并发或并行。 把它结合起来可能只会带来很小的性能增益甚至性能的损失。

通过查阅字典,你可以看到并发(来自拉丁语)意味着一起运行,汇合,同意; 因为在相同的资源上存在竞争,所以需要同步。 并行(来自希腊语)意味着在一边复制; 在同一时间做同样的事情。