并发和并行之间的区别是什么?
当前回答
并发是并行的广义形式。例如,并行程序也可以称为并发程序,但反向不成立。
可以在单个处理器上并发执行(多个线程,由调度器或线程池管理)在单个处理器上无法并行执行,但在多个处理器上无法。(每个处理器一个进程)分布式计算也是一个相关的主题,它也可以被称为并发计算,但反过来却不是,就像并行一样。
有关详细信息,请阅读本研究论文并行编程的概念
其他回答
(我很惊讶这样一个根本问题多年来都没有得到正确和巧妙的解决……)
简而言之,并发性和并行性都是计算的财产。
至于区别,以下是罗伯特·哈珀的解释:
首先要理解的是并行性与并发无关。并发与程序(或其组件)的不确定性组成有关。并行性与具有确定性行为的程序的渐近效率有关。并发是关于管理不可管理的事件:事件的发生是出于我们无法控制的原因,我们必须对此做出反应。用户单击鼠标时,窗口管理器必须做出响应,即使显示需要注意。这种情况本质上是不确定性的,但我们也在确定性设置中采用形式上的不确定性,假装组件以任意顺序发出事件信号,并且我们必须在事件发生时对其作出响应。非确定性组合是一种强大的程序结构思想。另一方面,并行性是关于确定性计算的子组之间的依赖性。其结果毋庸置疑,但有许多方法可以实现,有些方法比其他方法更有效。我们希望充分利用这些机会。
它们可以是程序中的各种正交财产。阅读此博客文章以获取更多插图。这篇文章稍微讨论了编程中组件的差异,比如线程。
注意,线程或多任务都是为更具体的目的服务的计算实现。它们可以与并行性和并发性相关,但不是以一种基本的方式。因此,它们很难成为开始解释的好条目。
还有一个亮点:(物理)“时间”几乎与这里讨论的财产无关。时间只是一种衡量实施的方式,以显示财产的重要性,但远非本质。仔细考虑一下“时间”在时间复杂性中的作用——这或多或少是相似的,即使在这种情况下,度量也往往更重要。
假设你有一个有两个线程的程序。程序可以通过两种方式运行:
Concurrency Concurrency + parallelism
(Single-Core CPU) (Multi-Core CPU)
___ ___ ___
|th1| |th1|th2|
| | | |___|
|___|___ | |___
|th2| |___|th2|
___|___| ___|___|
|th1| |th1|
|___|___ | |___
|th2| | |th2|
在这两种情况下,我们都有并发性,这仅仅是因为我们有多个线程在运行。
如果我们在具有单个CPU内核的计算机上运行此程序,操作系统将在两个线程之间切换,允许一次运行一个线程。
如果我们在带有多核CPU的计算机上运行这个程序,那么我们就可以同时并行运行两个线程。
并发性=>在共享资源的重叠时间段内执行多个任务时(可能最大化资源利用率)。
并行=>当单个任务被划分为可以同时执行的多个简单的独立子任务时。
我将提供一个与这里的一些流行答案有点冲突的答案。在我看来,并发是一个包含并行性的通用术语。并发适用于不同任务或工作单元在时间上重叠的任何情况。并行性更具体地适用于在同一物理时间评估/执行不同工作单元的情况。并行性存在的原因是加速了可以从多个物理计算资源中受益的软件。适用于并发的另一个主要概念是交互性。当从外部世界可以观察到任务的重叠时,互动性适用。交互性存在的原因是使软件能够响应真实世界的实体,如用户、网络对等体、硬件外围设备等。
并行性和交互性几乎完全独立于并发性。对于一个特定的项目,开发人员可能会关心其中之一,或者两者都不关心。它们往往会被混淆,尤其是因为线程这一令人厌恶的东西给了一个相当方便的原语来实现两者。
关于并行性的更多细节:
并行性存在于非常小的规模(例如处理器中的指令级并行性)、中等规模(例如多核处理器)和大型规模(例如高性能计算集群)。近年来,由于多核处理器的发展,软件开发人员暴露更多线程级并行性的压力越来越大。平行性与依赖性密切相关。依赖性限制了并行性的实现程度;如果一个任务依赖于另一个任务,则两个任务不能并行执行(忽略推测)。
程序员可以使用许多模式和框架来表达并行性:管道、任务池、数据结构上的聚合操作(“并行数组”)。
关于互动性的更多细节:
最基本和最常见的交互方式是使用事件(即事件循环和处理程序/回调)。对于简单的任务,事件是很好的。尝试使用事件执行更复杂的任务会导致堆栈撕裂(也称为回调地狱;也称为控制反转)。当你厌倦了事件时,你可以尝试更奇特的东西,比如生成器、协程(又称Async/Await)或合作线程。
出于对可靠软件的热爱,如果你想要的是交互性,请不要使用线程。
曲线几何非线性
我不喜欢Rob Pike的“并发不是并行;它更好”口号。并发既不比并行好,也不比并行差。并发性包括交互性,不能以更好/更差的方式与并行性进行比较。这就像说“控制流比数据更好”。
为什么存在困惑
由于这两个词的字典含义几乎相同,因此存在混淆:
并发:同时存在、发生或完成(dictionary.com)平行:非常相似,经常同时发生(梅里亚姆·韦伯斯特)。
然而,它们在计算机科学和编程中的使用方式却截然不同。以下是我的解释:
并发性:可中断性并行性:独立性
那么,我所说的上述定义是什么意思?
我将用一个现实世界的类比来澄清。假设你必须在一天内完成两项非常重要的任务:
获取护照完成演示文稿
现在,问题是任务1需要你去一个极其官僚的政府办公室,这让你排队等候4个小时才能拿到护照。同时,任务2是你的办公室需要的,这是一项关键任务。两者都必须在特定的一天完成。
案例1:顺序执行
通常,你会开车去护照办公室2个小时,排队4个小时,完成任务,开车回去两个小时,回家,再睡5个小时,然后完成演讲。
案例2:并发执行
但你很聪明。你要提前计划。你随身携带一台笔记本电脑,在排队等候的时候,你开始做你的演讲。这样,一旦你回到家里,你只需要额外工作1小时而不是5小时。
在这种情况下,这两项任务都是由您完成的,只是零碎的。您在排队等候时中断了护照任务,并进行了演示。当您的号码被呼叫时,您中断了演示任务,并切换到护照任务。由于这两项任务的可中断性,节省时间基本上是可能的。
并发性,IMO,可以理解为ACID中的“隔离”属性。如果子事务可以以任何交错的方式执行,那么两个数据库事务被认为是隔离的,并且如果两个任务是顺序完成的,那么最终结果是相同的。记住,对于护照和演示任务,你是唯一的刽子手。
案例3:并行执行
现在,既然你是个聪明的家伙,你显然是个更高级的人,而且你有一个助手。所以,在你开始护照任务之前,你给他打电话,告诉他准备演示文稿的初稿。你花了一整天的时间完成护照任务,回来看看你的邮件,然后找到了演示稿。他做得很扎实,再过两个小时就完成了一些编辑。
现在,你的助手和你一样聪明,他能够独立工作,而不需要经常要求你澄清。因此,由于任务的独立性,它们由两个不同的执行者同时执行。
还和我在一起吗?好吧
案例4:并行但不并行
还记得你的护照任务吗,你必须在排队等候的地方?因为这是你的护照,你的助手不能排队等你。因此,护照任务具有可中断性(您可以在排队等候时停止它,稍后当您的号码被呼叫时再继续),但没有独立性(您的助手不能代替您等待)。
案例5:并行但不并发
假设政府办公室有一个安全检查来进入办公场所。在这里,您必须移除所有电子设备并将其提交给官员,他们只会在您完成任务后归还您的设备。
在这种情况下,护照任务既不可独立,也不可中断。即使你在排队,你也不能做其他事情,因为你没有必要的设备。
同样地,假设演示是高度数学化的,你需要100%集中至少5小时。你不能在排队等候护照任务时做这件事,即使你随身携带笔记本电脑。
在这种情况下,演示任务是独立的(您或您的助手可以投入5小时的精力),但不能中断。
案例6:并发和并行执行
现在,假设除了指派你的助手参加演示外,你还随身携带一台笔记本电脑来完成护照任务。在排队等候时,您会看到您的助手在共享幻灯片组中创建了前10张幻灯片。你对他的工作发表了评论,并做了一些更正。后来,当你回到家时,你只需要15分钟,而不是2个小时来完成草稿。
这是可能的,因为演示任务具有独立性(你们中的任何一个都可以完成)和可中断性(你们可以停止它,稍后再继续它)。因此,您同时执行了两个任务,并并行执行了演示任务。
比方说,除了过于官僚之外,政府办公室也是腐败的。因此,你可以出示你的身份证,输入它,开始排队等待你的号码被呼叫,贿赂一名警卫和其他人来保持你在队伍中的位置,偷偷溜出去,在号码被呼叫之前回来,然后自己继续等待。
在这种情况下,您可以同时并行执行护照和演示任务。你可以偷偷溜出去,你的位置由你的助手掌握。然后你们两个都可以进行演示等。
回到计算机科学
在计算世界中,以下是每种情况的典型场景:
情况1:中断处理。情况2:只有一个处理器,但由于I/O,所有正在执行的任务都有等待时间。案例3:当我们谈论map reduce或hadoop集群时经常会看到。案例4:我认为案例4很罕见。任务是并发但不是并行的,这是不常见的。但这可能会发生。例如,假设您的任务需要访问只能通过处理器1访问的特殊计算芯片。因此,即使处理器-2是空闲的,而处理器-1正在执行其他任务,特殊计算任务也不能在处理器-2上继续。病例5:同样罕见,但不像病例4那样罕见。非并发代码可以是受互斥锁保护的关键区域。一旦启动,它必须执行到完成。然而,两个不同的关键区域可以在两个不同处理器上同时进行。案例6:IMO,关于并行或并发编程的大多数讨论基本上都在讨论案例6。这是并行和并发执行的混合和匹配。
并发和Go
如果你明白Rob Pike为什么说并发性更好,你必须明白原因是什么。你有一个非常长的任务,其中有多个等待期,你需要等待一些外部操作,如文件读取、网络下载。在他的演讲中,他所说的是,“把这一长串的任务分解,这样你就可以在等待的时候做一些有用的事情。”这就是为什么他会和各种各样的地鼠谈论不同的组织。
现在,围棋的力量来自于使用围棋关键词和频道,让这一突破变得非常容易。此外,在运行时中有很好的底层支持来调度这些goroutine。
但本质上,并发比并行好吗?
苹果比橙子好吗?
推荐文章
- 设计模式:工厂vs工厂方法vs抽象工厂
- 为什么处理排序数组比未排序数组慢?
- 构造函数何时抛出异常是正确的?
- Thread start()和Runnable run()有什么区别
- 什么是“一级”对象?
- 什么时候应该使用Debug.Assert()?
- 为什么浮点数不准确?
- IOException:进程不能访问文件“文件路径”,因为它正在被另一个进程使用
- 地图和字典的区别是什么?
- 跳跃表vs.二叉搜索树
- 在Swift中,什么相当于Objective-C的“@synchronized”?
- 是AsyncTask真的概念上有缺陷或我只是错过了一些东西?
- 递归还是迭代?
- Stack Overflow如何生成其seo友好的url ?
- AtomicInteger的实际用途