并发、并行和异步方法有什么区别?

What is the difference between concurrency, parallelism and asynchronous methods?

提问人:GurdeepS 提问时间:1/31/2011 最后编辑:LaurelGurdeepS 更新时间:11/7/2023 访问量:137893

问:

并发是指在不同的线程上并行运行两个任务。但是,异步方法并行运行,但在同一 1 个线程上。这是如何实现的?另外,并行性呢?

这三个概念有什么区别?

多线程异 并发

评论

19赞 Pointy 1/31/2011
术语“异步”可以意味着很多不同的东西。这些术语是相关的,但它们并不描述不相交的事物集。含义重叠并因情况而异。
2赞 Rick O'Shea 7/28/2018
因此,第一个并发是同时运行两个或多个进程。这样一来,并发就不是并行了。并行进程需要两个或多个内核,而并发进程可以共享单个内核。
0赞 Maxpm 1/10/2021
这几乎是 stackoverflow.com/questions/1050222/...的重复,它也有一些很好的答案。不同之处在于,这个问题询问的是异步方法,而另一个问题则没有。

答:

241赞 Lazarus 1/31/2011 #1

并发和并行实际上是与您正确推测的相同原理,两者都与同时执行的任务有关,尽管我会说并行任务应该是真正的多任务处理,“同时”执行,而并发可能意味着任务共享执行线程,同时仍然看起来是并行执行。

异步方法与前两个概念没有直接关系,异步用于呈现并发或并行任务的印象,但实际上异步方法调用通常用于需要在当前应用程序之外执行工作的进程,我们不想等待并阻止我们的应用程序等待响应。

例如,从数据库获取数据可能需要一些时间,但我们不想阻止 UI 等待数据。异步调用采用回调引用,并在向远程系统发出请求后立即将执行返回到代码。当远程系统执行所需的任何处理时,UI 可以继续响应用户,一旦它将数据返回到回调方法,该方法就可以根据需要更新 UI(或切换该更新)。

从用户的角度来看,它看起来像是多任务处理,但事实可能并非如此。


编辑

可能值得补充的是,在许多实现中,异步方法调用将导致线程启动,但这不是必需的,它实际上取决于正在执行的操作以及如何将响应通知回系统。

评论

78赞 Mark H 1/31/2011
我认为你在第一段中混淆了并行性和并发性。并发是指管理多个执行线程,其中并行性更具体地说,是多个执行线程同时执行。并发性是一个更广泛的术语,可以包含并行性。
11赞 Lazarus 1/31/2011
虽然这两个词非常相似并且可能会混淆(并且经常混淆),但它们确实有不同的定义:并发 = 同时存在、发生或完成。并行 = 相同或不同设备一次执行多个操作的表观或实际性能。如您所见,并行并不一定意味着并发,而可能只是看起来是并发的。归根结底,这些词经常互换使用,使用 n dev 是一个房间,您可能会得到 n+1 个定义;)
6赞 Lazarus 11/27/2012
@Mehrdad 如果你打算根据它们在营销材料中的使用来定义字典单词,那么我认为你可能会发现自己处于某种劣势。
22赞 Frank Radocaj 2/23/2014
错。在编程的上下文中,并发性是将代码“组合”为可以同时运行的逻辑位的能力。并行性(与并发性结合使用时)是获取所述代码并在 100 核机器上运行它。
6赞 4/26/2017
@FrankRadocaj说得对。并发意味着程序可以拆分为单元(单元本质上是线程),这些单元可以按任何顺序运行并具有确定的结果。并行意味着这些单元/线程在多个处理器上同时运行。
24赞 Aloysius Snuffleupagus 3/15/2014 #2

每个人都很难将异步与并行或并发相关联,因为异步不是并行或并发的反义词。它是 Synchronous 的反义词。它只是表示某些东西(在本例中为线程)是否将与其他内容(在本例中为另一个线程)同步。

2赞 rva 5/30/2017 #3

并发性与并行性: 并发:在一个时间点只能完成一个任务。示例:单个 CPU 处理器 并行性:在某一点上,我们可以执行多个任务。示例:双核或多核处理器

8赞 LONGHORN007 8/6/2017 #4

并发

并发意味着应用程序同时(并发)在多个任务上取得进展。好吧,如果计算机只有一个 CPU,则应用程序可能不会同时在多个任务上取得进展,但应用程序内部一次处理多个任务。在开始下一个任务之前,它不会完全完成一项任务。

排比

并行性意味着应用程序将其任务拆分为更小的子任务,这些子任务可以并行处理,例如同时在多个 CPU 上处理。

并发性与并行性详解

如您所见,并发性与应用程序如何处理它所处理的多个任务有关。应用程序可以一次(按顺序)处理一个任务,也可以同时(并发)处理多个任务。

另一方面,并行性与应用程序处理每个单独任务的方式有关。应用程序可以从头到尾按顺序处理任务,也可以将任务拆分为可以并行完成的子任务。

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

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

此外,应用程序既不能是并发的,也可以是并行的。这意味着它一次只处理一个任务,并且该任务永远不会分解为子任务以供并行执行。

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

从 http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html

176赞 Dimos 1/31/2018 #5

并发是指多个任务的执行是交错的,而不是每个任务一个接一个地按顺序执行。

并行性是指这些任务实际上是并行执行的。

enter image description here


异步是一个单独的概念(尽管在某些上下文中是相关的)。它指的是一个事件可能与另一个事件在不同的时间(不同步)发生。下图说明了同步执行和异步执行之间的区别,其中参与者可以对应于不同的线程、进程甚至服务器。

enter image description here

enter image description here

评论

23赞 contactmatt 3/12/2018
简单、有效的插图。
1赞 nos 2/18/2019
并发和异步一样吗?
2赞 Dimos 2/19/2019
这两个概念确实非常接近,但并不相同。在实践中,异步与动作(比如 A 和 B)之间的交互更相关,其中一个 (B) 由另一个 (A) 触发,以及第二个动作是否会等待第一个动作完成。并发性是一个更通用的术语,用于表示操作,这些操作也可以彼此无关,以及它们是按顺序执行还是交错执行。
3赞 Daniel 5/23/2020
所以异步主要是关于阻塞和非阻塞
9赞 aderchox 4/15/2021
你对并发的定义是错误的。并发既不意味着非并行,也不意味着并行,它只是意味着能够将程序分解为多个部分并任意重新排序,因此每个部分都可以由单独的线程运行,但这并不能说明是否并行运行。并发性是关于“同时处理很多事情”,并行是关于处理“同时做很多事情”。“并允许并行”维基百科上的数据
6赞 jeancallisti 8/22/2018 #6

平行:这是一个广义的术语,意味着两段代码“同时”执行。不管它是“真正的”并行性,还是通过某种巧妙的设计模式伪造的。关键是您可以同时启动“任务”,然后单独控制它们(使用互斥锁和所有适当的技巧)。 但通常你更喜欢只使用“并行”这个词来表示“真正的”并行性,如:你通过非合作的多任务处理来实现它(无论是通过CPU/GPU内核,还是只在软件级别,让操作系统在非常低的级别上管理它)。人们不愿意仅仅对假装并行性的复杂顺序代码说“并行”,例如,在浏览器窗口的 javascript 中会发现。因此,这个线程中的人说“异步与并行无关”的原因。嗯,确实如此,但不要混淆它们。

发 :没有并行性就不可能有并发性(无论是模拟的还是真实的,正如我上面解释的那样),但这个术语特别关注两个系统将在某个时候尝试同时访问同一资源的事实。它强调你将不得不处理这一事实。

异步:每个人都说异步与并行无关,但它为它铺平了道路(让事情并行与否的负担在你身上——继续阅读)。

“异步”是指并行性的一种表示形式,它形式化了并行性通常涉及的三个基本内容:1)定义任务的初始化(比如它何时开始以及它得到什么参数),2)完成后必须做什么,3)代码应该在两者之间继续做什么。

但它仍然只是语法(通常表示为回调方法)。在幕后,底层系统可能只是简单地决定这些所谓的“任务”只是代码片段,直到它完成当前正在执行的代码。然后它将它们一个接一个地堆放并按顺序执行。或不。它还可能为每个任务创建一个线程并并行运行它们。谁在乎啊?该部分不包括在概念;)

61赞 rahulaga-msft 12/19/2018 #7

有几种情况可以发生并发:

异步 — 这意味着您的程序执行非阻塞操作。例如,它可以通过 HTTP 发起对远程资源的请求,然后在等待收到响应的同时继续执行其他任务。这有点像你发了一封电子邮件,然后继续你的生活,而没有等待回复。

并行性— — 这意味着您的程序利用多核计算机的硬件,通过将工作分解为多个任务来同时执行任务,每个任务都在一个单独的内核上执行。这有点像洗澡时唱歌:你实际上在同一时间做两件事。

多线程 — 这是一种软件实现,允许并发执行不同的线程。多线程程序似乎同时执行多项操作,即使它在单核计算机上运行也是如此。这有点像通过各种 IM 窗口与不同的人聊天;虽然你实际上是在来回切换,但最终结果是你同时进行多个对话。

评论

5赞 wongz 6/7/2020
这些都是非常好的类比!谢谢。公平地说,并发性可以用你的多线程定义来定义吗?所以并发=单核上的多线程,看起来是同时发生的,但它真的来回切换得非常快?
6赞 Evans AB 3/3/2019 #8

这里有一些语义需要澄清:

并发性或并行性是资源争用的问题,而异步是关于控制流的问题。

不同的过程(或其组成操作)称为异步,当其处理顺序没有确定性实现时;换句话说,它们中的任何一个都有可能在任何给定时间 T 被处理。根据定义,多个处理器(例如 CPU 或 Person)可以同时处理其中的几个处理器;在单个处理器上,它们的处理是交错的(例如线程)。

当异步过程或操作共享资源时,它们称为并发;并发性是在任何给定时间争用的明确可能性 T. 当没有共享资源(例如不同的处理器和存储)时,并行性是微不足道的保证;否则必须解决并发控制问题。

因此,异步过程或操作可以并行处理,也可以与其他过程或操作同时处理。

10赞 Pedro Boechat 12/17/2019 #9

“同步和异步是编程模型。并发和并行是执行任务的方式......”。 来源:https://medium.com/better-programming/sync-vs-async-vs-concurrent-vs-parallel-5754cdb60f66

换句话说,sync 和 async 描述了程序在进行函数调用时的执行方式(是等待还是继续执行?),而 concurrent 和 parallel 描述了函数(任务)的执行方式(concurrent = 可能同时执行,parallel = 同时有效执行)。

评论

4赞 Moha the almighty camel 3/1/2020
Medium 不是来源,它是别人写的一篇关于他对某个主题的(错误)理解的文章,它并不能使他/她成为权威。
6赞 Pedro Boechat 3/1/2020
这是一个引文,因此是来源。这里的大多数答案都不是由任何领域的权威人士撰写的,作者给出的解释已经足够好了。
0赞 Moha the almighty camel 3/1/2020
在stackoverflow,你至少有一个投票系统,这是一个由专业人士组成的社区。任何人都可以在 medium 上写任何东西。这两者之间不是一个公平的比较。
4赞 Pedro Boechat 3/1/2020
任何人都可以在这里写任何东西,我不知道你为什么要选择 Medium。无论如何,我是一名专业的程序员,我赞同这种理解。我觉得它很优雅,因为它相对较短。
1赞 Pedro Boechat 6/17/2020
我认为假设它是不言自明的,这是我的坏处。
28赞 Dhirendra Gautam 4/15/2020 #10

并发意味着同时执行多个任务,但不一定同时执行。当您必须执行多个任务但您只有一个资源时,我们会选择并发。在单核环境中,并发是通过上下文切换实现的。

并行就像同时执行多个任务,就像可以一起唱歌和洗澡一样。现在,您正在并行执行这些任务。

术语异步与线程执行有关。在异步模型中,当一个任务被执行时,您可以切换到另一个任务,而无需等待前一个任务完成。

异步编程有助于我们实现并发。多线程环境中的异步编程是实现并行性的一种方式。

14赞 Testaccount 6/30/2020 #11

我将用简短而有趣的方式来介绍这些概念。

并发与并行 - 任务的执行方式。

在现实生活中举个例子:有一个挑战需要你 两人都吃了一整块蛋糕,唱了一整首歌。如果你是 唱完整首歌并完成蛋糕的最快人。所以 规则是你同时唱歌和吃饭。你是怎么做到的 不属于规则。你可以吃掉整个蛋糕,然后唱 整首歌,或者你可以吃半个蛋糕,然后唱半首歌,然后做 又是,等等。

并行性是一种特定的并发性,其中任务实际上是同时执行的。在计算机科学中,并行性可以 只能在多核环境中实现。

同步与异步 - 编程模型。

在同步中,将代码编写为从上到下按顺序执行的步骤 到底部。在异步编程模型中,将代码编写为任务。 然后并发执行。并发执行意味着 所有任务都可能同时执行。

3赞 YashKansara 7/30/2021 #12

我给出了现实世界的场景来解释 3 个主题 假设您想从艾哈迈达巴德前往孟买,但您不知道方式,因此您决定借助地图应用程序(谷歌地图)。

非常正常但效率低下的方式是,您可以在启动汽车之前观看完整的路径,然后开始驾驶并到达目的地。

  1. 并行 - 您可以不断驾驶和观察路径。
  2. 异步 - 你的朋友和你一起在车里,你给了他你的手机,打开了地图应用程序,并告诉他看地图并指导你。
  3. 并发 - 你开了几公里,把车停在一边,看地图,问路,然后重新开始开车,等等。
6赞 Alan 9/14/2021 #13

用类比来解释这些术语。

你的房子需要洗碗和洗衣服。

并发性:您不会等到完成一个后再开始另一个。例如,您可以先开始菜肴,也可以同时开始两者。它们可以按任何顺序完成,即即使您先开始洗碗,也可能先洗衣服。

并行性:家里有多个人在做这项工作;举个例子,你可以洗碗,另一个人可以洗衣服。

异步:你告诉别人洗衣服,你告诉别人洗碗。他们实际上可以是同一个人(即你告诉他们洗衣服,并立即告诉他们洗碗)。当他们完成每个工作时,他们会向你报告。

同步:你告诉别人洗碗。你等着他们。当他们完成时,你可以做其他事情(你可以告诉他们接下来洗衣服,或者你可以自己做,或者你可以完全做其他事情;关键是你在完成第一个任务时被阻止,你与他们同步)。

4赞 orustammanapov 12/22/2021 #14

总结一下

多个事情似乎同时发生时,并(具有在并发任务之间快速切换的能力;它们是并发的,因为每个任务都需要一块资源、CPU 等)

多件事真正同时发生时并(执行的线程数与执行的内核数密切相关)

异步简单地说是非阻塞的,当我们必须等待的事情不要让我们忙于等待时(需要某种通知机制才能从我们离开的点继续)

评论

0赞 clay 6/28/2022
在 Python 中被认为是异步的,这是阻塞。因此,异步并不意味着非阻塞。我不认为异步有真正的意义。此外,这里对并发和并行的区分似乎是武断和捏造的。await asyncio.sleep
0赞 orustammanapov 6/28/2022
嘿,@clay,通常是一种语言,或者(如本例中)结构。是什么让你认为,它必须一直保持无阻塞状态?只是为了澄清是不相等的(见:)那里的“等待”)。 也不是天生的,这里似乎是你的理解。每当您必须等待结果时,它就会变得阻塞。但是,在这种情况下,您不必等待任何事情,因此直到最后都不会阻塞。async/awaitasynchronousasync/awaitasync/awaitfire-and-forgetfire-and-forget
1赞 shvahabi 1/16/2022 #15

当经理有多个工作人员时,就会发生并行性,并且可以为每个工作人员分配单独的任务。工人做他们的工作,并向经理提供结果。如果任务不能完全分离,例如结果之间有一定的依赖性,或者需要相同的资源专用而没有其他推理,则并行度受制于这些约束,无法完全实现。

当经理有多个任务但只有较少的工作人员时,就会发生并发,因此一些工作人员被赋予了多个任务。任何给定多个任务的工作人员,将每个原始给定的任务分成几个步骤,并交错执行这些步骤,每个任务结果将在每个步骤完成后立即返回给经理。经理收到任务结果,而其他任务已启动并推进了几个步骤,但尚未完成。如果任何具有多个任务的工作人员决定在完成已启动任务的每个步骤之前不启动给定任务的单个步骤,则称为顺序性

从经理的角度来看,异步是上述两者中的任何一种混合或分离。当经理将任务分配给少数或足够多的工人时,他不应等待停滞不前,直到任何结果都得到回报。他可以做他的个人工作或其他任何事情,而工作正在取得进展。通常,工人不会决定如何将任务划分为多个步骤。控制倒置意味着经理决定步骤并将单个步骤交给工人。因此,当他从工作人员那里收到步骤结果时,给他另一个步骤,也许是另一个任务。受控制者也负责将后退步骤结果组合成任务结果。因此,异步性伴随着控制和协调的责任。如果任何工人被敦促按顺序工作,从经理的角度来看,他是一个同步工人。

总结正如猜测的那样,完全并行是一个无法实现的想法,除非在极少数情况下,大多数是微不足道的。因为现实伴随着相互依存的任务和共享资源以及缺乏工人。因此,并发性是现实。从经理的角度来看,如果这种并发性不妨碍他精细控制任务,那么它是最好的,如果为正,则称为异步。此外,计算机软件工程的最佳实践,在SOLID原则中由S增强,历史上使服务器成为称为微服务的单步运行者,这将控制权交还给客户端。因此,从服务器的角度来看,当前的情况是并发的,从客户端的角度来看是异步的

-3赞 clay 6/28/2022 #16

并发 + 并行:它们具有相同的含义。并发在韦氏词典中定义,主要定义是:“同时操作或发生”。并行意味着同样的事情。通常,执行线程在关系图上显示为线条,当这些线并行时,线程同时执行。一些来源表明“并发”和“并行”这两个术语之间存在一些区别,但这在很大程度上取决于您查看的来源,并且没有广泛同意的区别。

异步:从字面上看,这意味着不同步;这意味着当函数或过程返回时,任务不一定完成,并且通常该过程会返回某种 Future/Promise 或任务句柄,这些句柄可能会完成,也可能不会完成。

0赞 Harsha 5/7/2023 #17

我试图在 C# 编程的上下文中回答。

并发:并发是一种编程概念,程序员可以将程序划分为独立的部分(线程),并可以以与顺序无关的方式或按部分顺序执行它们,而不会影响结果。在实践中,我们使用多线程来实现这一点。在单核处理器上,任务(线程)以交错方法执行。这意味着,同一个内核从一个线程切换到另一个线程。因此,一次只执行一个线程。 在多核处理器上,任务(线程)以“并发+并行方法”执行,因为两个或多个任务(线程)可能在不同的内核上同时执行。

排比并行性是程序同时执行多个任务的能力,通常通过使用多个 CPU 或处理内核。如上所述,它可以与并发结合使用。

异步异步是一种编程技术,您可以在其中执行非块 I/O 操作。意味着,任务(线程)被保留,直到您从资源(数据库或网络请求)获得响应;但线程不需要等待任务完成。它可以执行一些其他任务(线程)。

注意:在这里,术语“任务”不应与TPL(任务并行库)中的“任务”混淆。