并发和并行之间的区别是什么?
当前回答
我将提供一个与这里的一些流行答案有点冲突的答案。在我看来,并发是一个包含并行性的通用术语。并发适用于不同任务或工作单元在时间上重叠的任何情况。并行性更具体地适用于在同一物理时间评估/执行不同工作单元的情况。并行性存在的原因是加速了可以从多个物理计算资源中受益的软件。适用于并发的另一个主要概念是交互性。当从外部世界可以观察到任务的重叠时,互动性适用。交互性存在的原因是使软件能够响应真实世界的实体,如用户、网络对等体、硬件外围设备等。
并行性和交互性几乎完全独立于并发性。对于一个特定的项目,开发人员可能会关心其中之一,或者两者都不关心。它们往往会被混淆,尤其是因为线程这一令人厌恶的东西给了一个相当方便的原语来实现两者。
关于并行性的更多细节:
并行性存在于非常小的规模(例如处理器中的指令级并行性)、中等规模(例如多核处理器)和大型规模(例如高性能计算集群)。近年来,由于多核处理器的发展,软件开发人员暴露更多线程级并行性的压力越来越大。平行性与依赖性密切相关。依赖性限制了并行性的实现程度;如果一个任务依赖于另一个任务,则两个任务不能并行执行(忽略推测)。
程序员可以使用许多模式和框架来表达并行性:管道、任务池、数据结构上的聚合操作(“并行数组”)。
关于互动性的更多细节:
最基本和最常见的交互方式是使用事件(即事件循环和处理程序/回调)。对于简单的任务,事件是很好的。尝试使用事件执行更复杂的任务会导致堆栈撕裂(也称为回调地狱;也称为控制反转)。当你厌倦了事件时,你可以尝试更奇特的东西,比如生成器、协程(又称Async/Await)或合作线程。
出于对可靠软件的热爱,如果你想要的是交互性,请不要使用线程。
曲线几何非线性
我不喜欢Rob Pike的“并发不是并行;它更好”口号。并发既不比并行好,也不比并行差。并发性包括交互性,不能以更好/更差的方式与并行性进行比较。这就像说“控制流比数据更好”。
其他回答
摘自Robert Love的《Linux系统编程》一书:
并发、并行和竞争线程创建两个相关但不同的现象:并发和相似两者都是苦乐参半的,涉及线程的成本以及它的好处。并发是两个或两个以上的能力要在重叠的时间段中执行的线程。平行度为同时执行两个或多个线程的能力。并发可以在没有并行性的情况下发生:例如,多任务处理在单处理器系统上。并行性(有时强调为真正的并行性)是一种特殊的并发形式,需要多个处理器(或一个能够支持多个引擎的处理器例如GPU)。通过并发,多个线程可以但不一定同时进行。具有并行,线程实际上并行执行,允许多线程程序以利用多个处理器。并发是一种编程模式,一种解决问题的方法。并行性是一种硬件特性,可以通过并发实现。两者都很有用。
这一解释与公认的答案一致。事实上,这些概念远比我们想象的简单。不要认为它们是魔法。并发大约是一段时间,而并行大约是同时进行的。
我喜欢Rob Pike的演讲:并发不是并行(这更好!)(幻灯片)(谈话)
Rob通常谈论Go,并且通常以直观直观的解释来解决并发与并行的问题!下面是一个简短的总结:
任务:让我们烧掉一堆过时的语言手册!一次一个!
并发:任务有许多并发分解!一个例子:
并行性:如果至少有2个地鼠同时工作或不工作,则前面的配置会并行出现。
并行编程执行有两种类型:非并行并行编程和并行并行编程(也称为并行)。
关键的区别在于,在人类看来,非并行并发中的线程似乎同时运行,但实际上它们并不运行。在非并行并发中,线程通过时间切片快速切换并轮流使用处理器。虽然并行有多个处理器可用,但多个线程可以同时在不同的处理器上运行。
参考文献:编程语言中的并发简介
并发编程关注的是看似重叠的操作,主要关注的是由于非确定性控制流而产生的复杂性。与并发程序相关的定量成本通常是吞吐量和延迟。并发程序通常受IO限制,但并不总是如此,例如并发垃圾收集器完全在CPU上。并发程序的教学示例是网络爬虫。该程序启动对网页的请求,并在下载结果可用时同时接受响应,从而累积一组已访问的网页。控制流是非确定性的,因为每次运行程序时,响应不一定以相同的顺序接收。这种特性会使调试并发程序变得非常困难。有些应用程序基本上是并发的,例如web服务器必须同时处理客户端连接。Erlang可能是未来最有前途的高度并发编程语言。并行编程涉及为提高吞吐量的特定目标而重叠的操作。通过使控制流具有确定性,避免了并发编程的困难。通常,程序生成并行运行的子任务集,父任务仅在每个子任务完成后才继续。这使得并行程序更容易调试。并行编程的难点是针对粒度和通信等问题的性能优化。后者在多核环境中仍然是一个问题,因为将数据从一个缓存传输到另一个缓存会产生相当大的成本。密集矩阵矩阵乘法是并行编程的一个教学示例,它可以通过使用Straasen的分治算法和并行攻击子问题来有效地解决。Cilk可能是共享内存计算机(包括多核)上最有前途的高性能并行编程语言。
从我的回答中复制:https://stackoverflow.com/a/3982782
只是为了给其他好答案添加更多的澄清:
基于处理的抽象(CPU作为一个完全可以想象的例子)能够在同一时刻运行唯一的任务的前提,
并发是一个关于处理抽象的故事:它可以在不同的任务之间切换。
并行是一个关于我们有多个处理抽象的故事(例如,我们的CPU有多个内核)。因此,这是我们的系统能够同时执行多个任务的原因(字面意思)。但这里没有提到处理的特定抽象(它们是否并发)。
这里的重点是这些故事的内容。
因此,当您阅读公认答案时,请注意:
并发是指两个或多个任务可以在重叠的时间段。
严格地说,我们可以根据这个定义得出结论,并行性本身就是并发性的前提。