并发编程和并行编程有什么区别?
并发编程和并行编程有什么区别? 我问谷歌,但没有find任何有助于我理解这种差异的东西。 你能举两个例子吗?
现在我发现这个解释: http : //www.linux-mag.com/id/7411 – 但是“并发是程序的一个属性”vs“并行执行是机器的属性”对于我来说是不够的 – 我还不能说什么是什么。
如果使用线程(并发编程)进行编程,则不一定会像这样执行(并行执行),因为它取决于机器是否可以处理多个线程。
这是一个视觉例子。 非线程机器上的线程:
-- -- -- / \ >---- -- -- -- -- ---->>
线程机器上的线程:
------ / \ >-------------->>
破折号表示执行的代码。 正如你所看到的,它们都是分开执行的,但是线程化的机器可以同时执行几个独立的部分。
并行编程涉及似乎重叠的操作,主要涉及由于非确定性控制stream而产生的复杂性。 与并发程序相关的定量成本通常是吞吐量和延迟。 并发程序往往是IO界限,但并不总是如此,例如并发垃圾收集器完全在CPU上。 一个并发程序的教学例子是一个networking爬虫。 该程序启动对网页的请求,并在下载结果可用时同时接受响应,累积一组已经访问过的页面。 控制stream是非确定性的,因为每次程序运行时,响应不一定以相同的顺序接收。 这个特性使得debugging并发程序非常困难。 某些应用程序基本上是并发的,例如Web服务器必须同时处理客户端连接。 Erlang也许是高度并发编程最有希望的语言。
并行编程涉及为了提高吞吐量的具体目标而重叠的操作。 并发编程的困难是通过使控制stream确定性来避开的。 通常,程序产生并行运行的子任务集合,并且只有每个子任务完成后,父任务才会继续。 这使并行程序更容易debugging。 并行编程的难点在于对粒度和通信等问题的性能优化。 后者在多核环境中仍然是一个问题,因为将数据从一个caching转移到另一个caching需要相当大的成本。 密集matrix乘法是并行编程的教学实例,可以通过Straasen的分治algorithm并行攻击子问题得到解决。 Cilk可能是在共享内存计算机(包括多核)上进行高性能并行编程的最有前途的语言。
https://joearms.github.io/published/2013-04-05-concurrent-and-parallel-programming.html
并行=两个队列和一台咖啡机。
并行=两个队列和两台咖啡机。
我相信并发编程指的是multithreading编程,它使您的程序运行多个线程,从硬件细节中突破。
并行编程是指专门devise你的程序algorithm,以利用可用的并行执行。 例如,你可以并行地执行一些algorithm的两个分支,期望它会比(如果你先检查第一个分支然后第二个分支)更早地(平均)得到结果。
将原始问题解释为并行/并行计算而不是编程 。
在并发计算中,两个计算都相互独立地前进 。 第二个计算不必等到第一个计算完成才能提前。 但是,它并没有说明这个机制是如何实现的。 在单核设置中,线程之间的挂起和交替是必需的(也称为先发制人的multithreading)。
在并行计算中,两个计算都是同时进行 – 这是字面上的同时。 这对于单个CPU是不可能的,需要多核设置。
与
根据: “在Node.js中并行vs并发” 。
我在一些博客中发现了这个内容。 认为这是有用的和相关的。
并发性和并行性并不是一回事。 如果两个任务的执行顺序没有预先确定,则两个任务T1和T2是并发的,
T1可以在T2之前执行完成,T2可以在T1之前执行完成,T1和T2可以在同一时刻同时执行(并行),T1和T2可以交替执行…如果两个并发线程由操作系统调度在一个单核心非SMT非CMP处理器上运行,您可能会得到并发性而不是并行性。 在多核,多处理器或分布式系统上可以进行并行处理。
并发性通常被称为程序的一个属性,是一个比并行更普遍的概念。
来源: https : //blogs.oracle.com/yuanlin/entry/concurrency_vs_parallelism_concurrent_programming
从处理器来看,可以用这张图来描述
从处理器来看,可以用这张图来描述
在编程中,并发是独立执行的进程的组成,而并行则是(可能相关的)计算的同时执行。
– 安德鲁·杰兰德 –
和
并发是独立执行计算的组成部分。 并发性是构build软件的一种方式,特别是作为编写与现实世界交互良好的干净代码的一种方式。 这不是平行的。
并发不是并行的,尽pipe它可以实现并行性。 如果你只有一个处理器,你的程序可以仍然是并行的,但不能并行。 另一方面,编写良好的并发程序可以在多处理器上并行运行。 那财产可能很重要
– Rob Pike –
为了理解这个区别,我强烈build议看看这个Rob Pike(Golang的创造者之一)的video。 并发不是并行的
并行编程发生在代码同时执行时,每个执行都独立于另一个。 所以通常不会有关于共享variables的假设,因为这不会发生。
然而,并发编程是由不同的进程/线程共享variables等执行的代码,因此在并发编程时,我们必须build立某种规则来决定哪个进程/线程先执行,这样我们才能确定会有保持一致,我们可以确定地知道会发生什么。 如果没有控制,所有的线程在同一时间计算,并将事物存储在相同的variables,我们怎么知道最终会期望什么? 也许一个线程比另一个线程更快,也许其中一个线程甚至在执行过程中停下来,另一个线程继续使用已损坏(尚未完全计算)的variables进行不同的计算,这种可能性是无止境的。 在这种情况下,我们通常使用并发编程而不是并行编程。
1.定义:
经典的任务调度可以是SERIAL
, PARALLEL
或CONCURRENT
SERIAL:
分析表明,任务必须按照已知的顺序被一个接一个地执行, 否则它将不起作用 。
即:很简单,我们可以忍受这一点
PARALLEL:
分析显示任务必须同时执行, 否则不起作用 。
- 在function上或时间上任何任务的任何故障将导致整个系统故障。
- 所有的任务必须有一个共同的可靠的时间感。
即:尽量避免这种情况,否则我们会在下午茶时间stream下眼泪。
CONCURRENT.
分析显示,我们不需要关心 。 我们不是粗心的,我们已经分析过了,没关系; 因此我们可以 随时使用任何可用的设施执行任何任务。
即:快乐的日子
通常情况下,在我称之为状态变化的已知事件中,可用调度发生变化。
2.这不是{Software | 编程}function,但系统devise方法:
人们经常认为这是关于软件的,但实际上它是一个系统devise的概念 , 在计算机之前
软件系统的推广速度有点慢, 很less有软件语言甚至试图解决这个问题。
如果您有兴趣尝试一下, 您可以 尝试查找 TRANSPUTER语言occam
。
( occam
有许多主要创新(如果不是首屈一指的)function,包括对PAR
和SER
代码部分执行构造函数的明确的语言支持,其他语言主要受到近年来可用的大规模并行处理器arrays时代的困扰,重新发明了超过35年前使用的InMOS Transputers(!!!))
3.一个好的系统devise需要注意的是:
简而言之, 系统devise解决以下问题:
VERB – 你在做什么。 ( 操作或algorithm )
名词 – 你在做什么。 ( 数据或界面 )
当 –启动,时间表,状态变化, SERIAL
, PARALLEL
, CONCURRENT
在哪里 –一旦你知道什么时候发生,那么你可以说,他们可以发生的地方,而不是之前。
为什么 –这是一个办法吗? 还有其他的方法吗? 有没有最好的方法?
..最后但并非最不重要.. 如果你不这样做,怎么办?
4. PARALLEL与SERIAL方法的可视化例子:
最近的 并行架构可用于2014年在16,64,104并行RISC uP-sarrays上的应用
从上世纪90年代初期开始,Inmos Transputer CPU演示video就是真正的平行历史的一部分
祝你好运
它们是两个短语,从(很less)不同的观点来描述相同的事物。 并行编程是从硬件的angular度来描述情况 – 至less有两个处理器(可能在一个物理包中)并行处理一个问题。 并发编程是从软件的angular度来描述更多的东西 – 两个或多个动作可能在同一时间(同时)发生。
这里的问题是,人们试图用这两个短语来划分清楚的区别,而没有真正存在的区别。 现实是,他们试图划分的界限几十年来一直模糊不清,随着时间的推移变得越来越模糊。
他们试图讨论的是,曾经一度,大多数电脑只有一个CPU。 当你在单个CPU上执行多个进程(或线程)时,CPU一次只能执行其中一个线程的一条指令。 并发的出现是一种幻想–CPU在不同线程间执行指令的切换速度足够快,以至于人类感知(任何小于100毫秒左右的瞬间),它看起来像是在做很多事情。
与此形成鲜明对比的是具有多个CPU的计算机或具有多个内核的CPU,因此该机器正在同时执行来自多个线程和/或进程的指令; 执行一个代码对另一个执行代码不会有任何影响。
现在的问题是:这样一个清晰的区别几乎从来没有存在过。 计算机devise人员实际上是相当聪明的,所以他们很久以前就注意到(例如)当你需要从一个I / O设备(如磁盘)读取一些数据时,花了很长时间(就CPU周期而言)完。 而不是在发生这种情况时让CPU空闲,他们想出了让一个进程/线程发出一个I / O请求的各种方法,并且在I / O请求完成时让其他进程/线程的代码在CPU上执行。
所以,在多核CPU成为常态之前,我们就有了multithreading并行发生的操作。
这只是冰山一angular。 数十年前,计算机也开始提供另一种水平的并行性。 同样,作为一个相当聪明的人,计算机devise师注意到,在很多情况下,他们的指令并不相互影响,所以可以同时执行同一个stream中的多条指令。 Control Data 6600就是一个早期的例子。它是1964年推出的世界上最快的计算机(相当广泛),而且大部分相同的基本架构目前仍在使用。 它跟踪每条指令所使用的资源,并且拥有一套执行单元,一旦它们所依赖的资源变得可用,就立即执行指令,这与最新的英特尔/ AMD处理器的devise非常相似。
但是(正如过去常说的广告)等待 – 这不是全部。 还有另外一个devise元素增添了更多的混乱。 它被赋予了不同的名称(例如,“超线程”,“SMT”,“CMP”),但是它们都指向相同的基本思想:可以同时执行多个线程的CPU,使用一些资源的组合对于每个线程是独立的,以及在线程之间共享的一些资源。 在典型情况下,这与上面概述的指令级并行机制相结合。 为此,我们有两套(或更多)架构寄存器。 然后我们有一套执行单元,只要有必要的资源可用就可以执行指令。 这些通常很好地结合在一起,因为来自不同stream的指令几乎不依赖于相同的资源。
那么,当然,我们可以使用多核的现代系统。 这里很明显,对吗? 我们有N个(目前介于2到256之间的)单独的内核,它们可以同时执行指令,所以我们有明确的真实并行机制 – 在一个进程/线程中执行指令,不会影响另一个执行指令。
那么,有点。 即使在这里,我们有一些独立的资源(寄存器,执行单元,至less一级caching)和一些共享资源(通常至less是最低级别的caching,绝对是内存控制器和内存带宽)。
总而言之,人们喜欢在共享资源和独立资源之间进行对比的简单场景几乎不会在现实生活中发生。 在共享所有资源的情况下,我们最终会遇到类似MS-DOS的问题,我们一次只能运行一个程序,而在运行另一个程序之前,我们必须停止运行一个程序。 在完全独立的资源下,我们有N台运行MS-DOS的计算机(甚至没有networking来连接它们),根本无法共享任何东西(因为如果我们甚至可以共享一个文件,那么这是一个共享资源,违反了没有共享的基本前提)。
每个有趣的案例都涉及独立资源和共享资源的组合。 每一台合理的现代计算机(以及很多现代计算机)都至less有一些能力可以同时进行至less一些独立的操作,几乎任何比MS-DOS更复杂的东西都至less可以利用它有些程度。
人们喜欢画的“同时”和“平行”之间的清晰划分不存在,几乎从来没有。 人们喜欢将其归类为“并发”,但通常还涉及至less一种并且往往更多不同types的并行执行。 他们喜欢将其归类为“并行”,通常涉及共享资源,并且(例如)一个进程在使用两者共享的资源时阻塞另一个进程。
试图在“平行”和“并发”之间划清界限的人们生活在一个从未真正存在的电脑中。
我明白不同的是:
1)并行 – 使用共享资源并行运行2)并行 – 使用不同的资源并行运行
所以,即使在点(2)或者在正在执行的操作(1)中使用相同储备的两件事情上,两件事情可以在同一时间独立于彼此发生。
虽然并行和并行之间的区别并不完全一致,但许多作者作出以下区别:
- 在并发计算中,程序是可以在任何时刻执行多个任务的程序。
- 在并行计算中,一个程序是多个任务密切合作解决问题的程序。
所以并行程序是并发的,但是像多任务操作系统这样的程序也是并发的,即使它只在一个只有一个核心的机器上运行,因为多个任务可以在任何时刻进行。
来源 :并行编程介绍Peter Pacheco
并发是程序的一个属性,并行执行是机器的一个属性。 什么并发部分应该和不应该并行执行,只有当确切的硬件已知时才能得到回答。 在处理显式并行编程时,我可能会添加哪些内容会导致最不愉快的结论。使用显式并行程序不能保证效率和可移植性。
Concurrent programming
在一般意义上指代我们定义的任务可以以任何顺序发生的环境。 一个任务可以在另一个任务之前或之后发生,并且可以同时执行一些或全部任务。
Parallel programming
是指在不同处理器上同时执行并发任务。 因此,所有的并行编程都是并行的,但不是所有的并行编程都是并行的。
来源: PThreads编程 – 更好的多处理的POSIX标准,Buttlar,Farrell,Nichols