并发和并行有什么区别?
赞赏的例子.
并发是指两个或多个任务可以在重叠的时间段内启动,运行和完成.这并不一定意味着它们都会在同一时刻运行.例如,在单核机器上进行多任务处理.
并行时任务字面上的同时运行,例如,在多核处理器上.
引用Sun的多线程编程指南:
并发:当至少两个线程正在进行时存在的条件.一种更通用的并行形式,可以包括时间切片作为虚拟并行的一种形式.
并行性:当至少两个线程同时执行时出现的情况.
存在混淆,因为这两个词的字典含义几乎相同:
并发:同时存在,发生或完成(dictionary.com)
平行:非常相似,经常同时发生(merriam webster).
然而,它们在计算机科学和编程中的使用方式却截然不同.这是我的解释:
并发:中断性
并行性:可独立性
那么上面的定义是什么意思呢?
我将用现实世界的比喻来澄清.假设您必须在一天内完成2项非常重要的任务:
拿到护照
完成演示
现在,问题是任务-1要求你去一个极端官僚的政府办公室,让你等了4个小时才能拿到你的护照.同时,办公室需要任务2,这是一项关键任务.两者都必须在特定日期完成.
通常情况下,你将开车到护照办公室2小时,在线等待4个小时,完成任务,开车两个小时,回家,再远离5个小时,完成演示.
但你很聪明.你提前计划.你随身携带一台笔记本电脑,在排队等候时,你开始制作你的演示文稿了.这样,一旦你回到家,你只需要额外工作1小时而不是5小时.
在这种情况下,两个任务都由您完成,只是分片.你在排队等候的时候打断了护照任务并进行了演示.当您的号码被呼叫时,您中断了演示任务并切换到护照任务.由于两个任务的中断性,基本上可以节省时间.
并发,IMO,应该被视为数据库的ACID属性中的"隔离".如果以任何交错方式在每个中执行子事务,并且最终结果与两个任务是按顺序完成相同,则两个数据库事务满足隔离要求.请记住,对于护照和演示任务,您是唯一的刽子手.
现在,既然你是一个聪明的家伙,你显然是一个更高级的,你有一个助手.因此,在您离开开始护照任务之前,您打电话给他并告诉他准备演示文稿的初稿.你花了一整天的时间完成护照任务,回来看看你的邮件,然后找到演示稿.他已经完成了相当可靠的工作,并且在2个小时内进行了一些编辑,你最终确定了它.
既然如此,你的助手就像你一样聪明,他能够独立工作,而不需要经常要求你澄清.因此,由于任务的可独立性,它们由两个不同的执行者同时执行.
还在我这儿?好的...
记住你的护照任务,你必须在排队等候?由于这是您的护照,您的助手不能排队等候.因此,护照任务具有可中断性(您可以在排队等候时停止它,并在稍后调用您的号码时恢复它),但不具有可独立性(您的助手不能代替您等待).
假设政府办公室有进入房屋的安全检查.在这里,您必须删除所有电子设备并将其提交给官员,并且他们仅在您完成任务后返回您的设备.
在这种情况下,护照任务既不可独立也不可中断.即使您在排队等候,也无法使用其他设备,因为您没有必要的设备.
同样地,假设演示文稿在数学上具有如此高的数学性能,您需要100%浓度至少5小时.即使您有自己的笔记本电脑,也不能在排队等待护照任务时这样做.
在这种情况下,演示任务是可独立的(您或您的助手可以投入5小时的集中精力),但不可中断.
现在,请说除了将助理分配到演示文稿之外,您还随身携带一台笔记本电脑到护照任务.在排队等候时,您会看到助手已在共享卡组中创建了前10张幻灯片.您通过一些更正发送有关其工作的评论.之后,当你到家时,而不是2小时完成选秀,你只需要15分钟.
这是可能的,因为演示任务具有可独立性(你们中的任何一个都可以做到)和可中断性(你可以停止并稍后恢复).因此,您同时执行了这两个任务,并并行执行了演示任务.
让我们说,除了过于官僚之外,政府办公室也是腐败的.因此,你可以显示你的身份证明,输入它,开始排队等候你的号码,贿赂一个警卫和其他人来保持你的位置,潜行,在你的电话号码被召回之前回来,并恢复等待你自己.
在这种情况下,您可以同时并行执行护照和演示任务.你可以偷偷溜出来,你的位置由你的助手保管.然后你们两个都可以进行演示等.
在计算世界中,以下是每种情况的典型示例场景:
案例1:中断处理.
情况2:当只有一个处理器时,由于I/O,所有执行的任务都有等待时间.
案例3:当我们谈论map-reduce或hadoop集群时常常会看到.
案例4:我认为案例4很少见.任务并发但不并行的情况并不常见.但它可能发生.例如,假设您的任务需要访问一个特殊的计算芯片,只能通过处理器1访问.因此,即使处理器-2是空闲的并且处理器-1正在执行某些其他任务,特殊计算任务也不能在处理器-2上进行.
案例5:也很少见,但并不像案例4那么罕见.非并发代码可以是受互斥锁保护的关键区域.一旦启动,它必须执行完成.但是,两个不同的关键区域可以在两个不同的处理器上同时进行
案例6: IMO,关于并行或并发编程的大多数讨论基本上都在谈论案例6.这是并行和并发执行的混合和匹配.
并发和Go
如果你看到为什么Rob Pike说并发性更好,你必须明白原因是.您有一个非常长的任务,其中有多个等待期间,您等待一些外部操作,如文件读取,网络下载.在他的演讲中,他所说的只是,"只是打破这个长时间的顺序任务,这样你就可以在等待的时候做一些有用的事情."这就是为什么他谈论不同组织与各种地鼠.
现在,Go的优势在于通过go
关键字和渠道轻松实现这一目标.此外,在运行时中有很好的底层支持来安排这些goroutine.
但基本上,并发性更好的是并发性?
苹果比橘子更受青睐吗?
我喜欢Rob Pike的演讲:并发不是并行(它更好!) (幻灯片) (谈话)
Rob经常谈论Go,并且通常以直观和直观的方式解决并发与并行的问题!这是一个简短的总结:
任务:让我们烧掉一堆过时的语言手册!一次一个!
并发:任务同时分解很多!一个例子:
并行性:如果至少有2个gophers同时工作,则先前的配置会并行发生.
添加其他人说的话:
并发性就像让一个变戏法者玩弄很多球.无论看起来如何,这个变戏法者每次只能抓住/投掷一个球.平行主义让多个变戏法者同时玩弄球.
假设你有一个有两个线程的程序.该程序可以以两种方式运行:
Concurrency Concurrency + parallelism (Single-Core CPU) (Multi-Core CPU) ___ ___ ___ |th1| |th1|th2| | | | |___| |___|___ | |___ |th2| |___|th2| ___|___| ___|___| |th1| |th1| |___|___ | |___ |th2| | |th2|
在这两种情况下,我们都有并发性,因为我们有多个线程在运行.
如果我们在具有单个CPU内核的计算机上运行此程序,则操作系统将在两个线程之间切换,允许一次运行一个线程.
如果我们在具有多核CPU的计算机上运行该程序,那么我们将能够并行运行两个线程- 在同一时间并排运行.
并发:如果单个处理器解决了两个或更多问题.
并行性:如果多个处理器解决了一个问题.
我将尝试用一个有趣且易于理解的例子来解释.:)
假设一个组织组织一个国际象棋锦标赛,其中10名球员(具有相同的国际象棋比赛技巧)将挑战职业冠军棋手.因为国际象棋是1:1的比赛,所以组织者必须以时间有效的方式进行10场比赛,以便他们能够尽快完成整个赛事.
希望以下场景可以轻松描述进行这10款游戏的多种方式:
1)SERIAL - 让我们说专业人士一个接一个地与每个人一起玩,即用一个人开始和完成游戏,然后用下一个人开始下一个游戏,依此类推.换句话说,他们决定按顺序进行比赛.因此,如果一场比赛需要10分钟才能完成,那么10场比赛将需要100分钟,同时假设从一场比赛转换到另一场比赛需要6秒,然后10场比赛将是54秒(约1分钟).
所以整个活动大约在101分钟内完成(最糟糕的方法)
2)CONCURRENT - 让我们说专业人员轮到他并转移到下一位玩家所以所有10名玩家同时玩,但专业玩家不是一次两个人,他轮到他并转向下一个人.现在假设职业球员需要6秒才能轮到他,并且职业球员的转换时间为两个球员,而且两名球员的转换时间为6秒,因此回到第一位球员的总转换时间将是1分钟(10x6秒).因此,当他回到第一个人,事件开始时,已经过了2分钟(10xtime_per_turn_by_champion + 10xtransition_time = 2mins)
假设所有玩家需要45秒完成他们的转弯,所以基于SERIAL事件的每场比赛10分钟,没有.比赛结束前的轮数应为600 /(45 + 6)= 11轮(约)
所以整个事件将在11xtime_per_turn_by_player _&_ champion + 11xtransition_time_across_10_players = 11x51 + 11x60sec = 561 + 660 = 1221sec = 20.35mins(约)完成
从101分钟到20.35分钟进行改进(更好的方法)
3)PARALLEL - 让组织者获得一些额外的资金,因此决定邀请两名职业冠军球员(两名同样有能力)并将两组相同的10名球员(挑战者)分成两组,每组5名,并分配给两名冠军,即一名每组.现在事件正在这两组中并行进行,即至少有两名球员(每组一名)与他们各自组中的两名职业球员比赛.
但是在团队中,专业玩家一次只能拿一个玩家(即顺序),所以在没有任何计算的情况下,您可以很容易地推断出整个事件将在101/2 = 50.5分钟内完成大约完成
从101分钟到50.5分钟看到改进(好的方法)
4)CONCURRENT + PARALLEL - 在上面的场景中,假设两名冠军球员将同时与各自组中的5名球员一起比赛(阅读第2分),所以现在各组之间的比赛并行运行,但在组内他们同时运行.
因此,一组中的游戏将在11xtime_per_turn_by_player _&_ champion + 11xtransition_time_across_5_players = 11x51 + 11x30 = 600 + 330 = 930sec = 15.5mins(近似)中大致完成
因此整个事件(涉及两个这样的并行运行组)将在15.5分钟内完成
从101分钟到15.5分钟进行改进(最佳方法)
注意:在上面的场景中,如果用10个类似的作业替换10个玩家,用两个CPU核心替换两个专业玩家,那么下面的顺序将保持不变:
SERIAL> PARALLEL> CONCURRENT> CONCURRENT + PARALLEL
(注意:此顺序可能会因其他方案而改变,因为此排序高度依赖于作业的相互依赖性,通信需要黑白作业和转换开销黑白作业)
简单的例子:
同时是:"两个队列访问一台ATM机"
并行是:"两个队列和两台ATM机"
concurency:具有共享资源潜力的多个执行流程
例如:两个线程竞争I/O端口.
paralelism:将问题分成多个相似的块.
例如:通过在文件的每一半上运行两个进程来解析大文件.
他们解决不同的问题.并发解决了CPU资源稀缺和许多任务的问题.因此,您可以通过代码创建线程或独立的执行路径,以便在稀缺资源上共享时间.直到最近,由于CPU可用性,并发性一直占据讨论的主导地位.
并行性解决了找到足够的任务和适当的任务(可以正确拆分的任务)并在丰富的CPU资源上分配它们的问题.并行性一直存在,但它已经走到了前列,因为多核处理器非常便宜.
并发编程执行有两种类型:非并行并发编程和并行并发编程(也称为并行).
关键的区别在于,对于人眼来说,非并行并发中的线程似乎同时运行,但实际上并非如此.在非并行并发线程中,快速切换并轮流使用处理器通过时间切片.虽然并行性有多个处理器可用,但多个线程可以同时在不同的处理器上运行.
参考:编程语言中的并发简介
想象一下,通过观看视频教程来学习新的编程语言.您需要暂停视频,应用代码中所说的内容然后继续观看.这是并发性的.
现在你是一名专业程序员.而且您喜欢在编码时聆听平静的音乐.这就是并行性.
请享用.
并行性是在一个multiple cores per CPU
或多个上同时执行进程multiple CPUs (on a single motherboard)
.
并发是指通过使用分配 CPU时间(时间片)的调度算法实现并行性.进程是交错的.single core/CPU
单位:
单个CPU中的1个或多个内核(几乎所有现代处理器)
主板上有1个或多个CPU (想想旧式学校服务器)
1个应用程序是1个程序(想想Chrome浏览器)
1个程序可以有1个或多个进程(认为每个Chrome浏览器选项卡都是一个进程)
1个进程可以有1个程序中的1个或多个线程(Chrome选项卡在1个线程中播放Youtube视频,另一个线程为评论部分生成,另一个用于用户登录信息)
因此,1个程序可以有1个或多个执行线程
1个进程是thread(s)+allocated memory resources by OS
(堆,寄存器,堆栈,类内存)
并发 =>在具有共享资源的重叠时间段内执行多个任务(可能最大化资源利用率).
Parallel =>当单个任务被分成多个可以同时执行的简单独立子任务时.
可以将其视为服务队列,其中服务器只能为队列中的第一个作业提供服务.
1个服务器,1个作业队列(5个作业) - >没有并发,没有并行性(只有一个作业正在服务完成,队列中的下一个作业必须等到服务作业完成且没有其他服务器到服务吧)
1个服务器,2个或更多不同的队列(每个队列有5个作业) - >并发(因为服务器与队列中的所有第一个作业共享时间,相同或加权),仍然没有并行性,因为在任何时刻,只有一个工作正在维修.
2个或更多服务器,一个队列 - >并行(在同一时刻完成2个作业)但没有并发(服务器不共享时间,第三个作业必须等到服务器完成一个.)
2个或更多服务器,2个或更多不同的队列 - >并发和并行
换句话说,并发是共享时间来完成一项工作,它可能需要相同的时间来完成它的工作,但至少它可以提前开始.重要的是,工作可以分成较小的工作,这允许交错.
并行性是通过并行运行的更多CPU,服务器,人员等实现的.
请记住,如果资源是共享的,那么就无法实现纯粹的并行性,但这是并发性最佳实际应用的地方,占用了另一个不需要该资源的工作.
我将提供一个与这里的一些流行答案有点冲突的答案.在我看来,并发性是一个包含并行性的通用术语. 并发适用于不同任务或工作单元及时重叠的任何情况. 并行性更具体地适用于在相同物理时间评估/执行不同工作单元的情况.平行主义的存在理由是加速可以从多个物理计算资源中受益的软件.适合并发的另一个主要概念是交互性. 当从外部世界观察到任务的重叠时,交互性适用.互动的存在理由是制作能够响应现实世界实体的软件,如用户,网络同行,硬件外围设备等.
并行性和交互性几乎完全是并发的独立维度.对于特定项目,开发人员可能会关心其中之一,两者都不关心.他们倾向于混淆,尤其是因为线程的憎恶给了两者相当方便的原语.
关于并行性的更多细节:
并行性存在于非常小的规模(例如处理器中的指令级并行性),中等规模(例如多核处理器)和大规模(例如高性能计算集群).由于多核处理器的增长,近年来软件开发人员面临更多线程级并行性的压力越来越大.并行性与依赖性概念密切相关.依赖性限制了并行度的实现程度; 如果一个依赖于另一个任务,则无法并行执行两个任务(忽略推测).
程序员使用许多模式和框架来表达并行性:管道,任务池,数据结构上的聚合操作("并行数组").
关于交互性的更多细节:
进行交互的最基本和最常见的方式是事件(即事件循环和处理程序/回调).对于简单的任务,事件很棒.尝试用事件做更复杂的任务进入堆栈翻录(又名回调地狱;又称控制反转).当你厌倦了事件时,你可以尝试更多奇特的东西,如生成器,协同程序(aka Async/Await)或协作线程.
对于对可靠软件的热爱,如果你想要的是交互性,请不要使用线程.
Curmudgeonliness
我不喜欢Rob Pike的"并发性不是并行性;它更好"的口号.并发性既不比并行性更好也不差.并发性包括交互性,无法以更好/更差的方式与并行性进行比较.这就像说"控制流程比数据更好".
在电子串行和并行中表示一种静态拓扑,确定电路的实际行为.当没有并发性时,并行性是确定性的.
为了描述动态的,与时间相关的现象,我们使用术语顺序和并发.例如,可以通过特定的任务序列(例如,食谱)获得某个结果.当我们与某人交谈时,我们正在制作一系列单词.然而,实际上,许多其他过程在同一时刻发生,因此,与某个动作的实际结果一致.如果很多人同时说话,并发谈话可能会干扰我们的序列,但这种干扰的结果是事先不知道的.并发引入了不确定性.
串行/并行和顺序/并发表征是正交的.这方面的一个例子是数字通信.在串行适配器中,数字消息在时间上(即顺序地)沿着相同的通信线路(例如,一条线路)分布.在并行适配器中,这也在并行通信线路(例如,许多线路)上划分,然后在接收端重建.
让我们想象一个有9个孩子的游戏.如果我们将它们作为链条处理,首先给出一条消息并在结束时接收它,我们将进行串行通信.更多的单词组成了消息,由一系列通信统一组成.
I like ice-cream so much. > X > X > X > X > X > X > X > X > X > ....
这是在串行基础设施上重现的顺序过程.
现在,让我们将图像划分为3个组.我们将这个短语分为三个部分,第一个给我们左边的线的孩子,第二个给中心线的孩子,等等.
I like ice-cream so much. > I like > X > X > X > .... > .... > ice-cream > X > X > X > .... > so much > X > X > X > ....
这是在并行基础设施上再现的顺序过程(尽管仍然部分序列化).
在这两种情况下,假设孩子之间有完美的沟通,结果是事先确定的.
如果有其他人与您同时与第一个孩子交谈,那么我们将同时进行.我们不知道基础设施将考虑哪个流程,因此最终结果未提前确定.
并发性是并行性的一般形式.例如,并行程序也可以被称为并发,但反向不是真的.
可以在单个处理器上同时执行(多个线程,由调度程序或线程池管理)
在单个处理器上但在多个处理器上不能并行执行.(每个处理器一个进程)
分布式计算也是一个相关的主题,它也可以称为并发计算,但反之则不行,如并行性.
有关详细信息,请阅读本研究论文 "并发编程概念"