如何阐明asynchronous和并行编程之间的区别?

许多平台都提高了asynchronous和并行性,作为提高响应速度的手段。 我通常会理解这种差异,但经常发现很难在我自己的脑海中以及在其他人身上expression。

我是一个workaday程序员,并经常使用asynchronous和callback。 平行主义感觉异乎寻常。

但我觉得他们很容易混淆,特别是在语言devise层面。 会喜欢清楚地描述他们如何相关(或不相关),以及哪些程序类别最适用。

当你asynchronous运行某个东西的时候,这意味着它是非阻塞的,你可以在不等待它完成并执行其他事情的情况下执行它。 并行是指同时运行多个事物。 如果您可以将任务分解为独立的工作,则并行性效果良好。

以渲染3Danimation的帧为例。 要渲染animation需要很长时间,所以如果要从animation编辑软件中启动渲染,则需要确保它是asynchronous运行的,所以它不会locking您的UI,并且可以继续执行其他操作。 现在,该animation的每一帧也可以被认为是一个单独的任务。 如果我们有多个CPU /内核或多个机器可用,我们可以并行渲染多个帧,以加快整体工作量。

我认为主要的区别在于并发并行

asynchronouscallback通常是expression并发性的一种方式(工具或机制),即一组实体可能彼此交谈并共享资源。 在asynchronous或callback的情况下,通信是隐含的,而资源共享是可选的(考虑在远程机器中计算结果的RMI)。 正确地注意到,这通常是在考虑到响应的情况下完成的。 不要等待长时间的延迟事件。

并行编程通常将吞吐量作为主要目标,而延迟时间(即单个元素的完成时间)可能比等效的顺序程序更差。

为了更好地理解并发性和并行性之间的区别,我将引用Daniele Varacca的并发概率模型,这是并发理论的一组注意事项:

计算模型是一个并发模型,它能够将系统表示为由独立的自治组件组成,可能相互通信。 并发的概念不应与并行的概念混淆。 并行计算通常涉及在几个处理器之间分配工作的中央控制器。 在并发性方面,我们强调组件的独立性,以及它们彼此沟通的事实。 平行主义就像古埃及,法老决定在那里,奴隶在工作。 并发就像现代的意大利,每个人都在做他们想要的东西,而且都使用手机。

总而言之 ,并行编程在某些情况下是并发性的特殊情况,其中单独的实体协作以获得高性能和吞吐量(通常)。

asynchronous和callback只是一个让程序员expression并发的机制。 考虑使用诸如master / worker或map / reduce之类的众所周知的并行编程devise模式是由使用这种较低级别机制(asynchronous)来实现更复杂的集中式交互的框架来实现的。

对于新程序员来说,asynchronous和并行编程很难理解

asynchronous编程asynchronous编程是一种主要是单线程编程的范例,即“遵循一个连续执行的线程”。

正如我们所看到的,尽pipeA,B,C事件同时发生, BC无法知道A的事物何时完成

  |----A-----| |-----B-------| |-------C------| 

并行编程并行编程是一种主要是multithreading编程的范例,即“遵循许多并发执行的许multithreading”。

这里ABC所有的任务是同时发生的, BC不会等待,因为所有的任务都是不同的,并且一次都发生( ABC由三个不同的线程处理

 |-----A-----| |-----B-----| |-----C-----| 

所以你可能会问自己:“这些听起来像是一样的交易!”

实际上他们绝不是这个意思。 通过asynchronous调用,您无法控制线程或线程池(线程的集合),并依赖于系统来处理请求。 使用并行编程,您可以更好地控制任务块,甚至可以创build多个线程,以由处理器中的给定数量的内核来处理。 然而,每次调用或拆卸线程都是非常系统密集的,因此在创build编程时必须格外小心。

这篇文章解释得非常好: http : //urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

它有关于asynchronous编程的内容:

asynchronous调用用于防止应用程序中的“阻塞”。 [这样的]调用将在已经存在的线程(如I / O线程)中分离出来,并在可能的时候完成任务。

这关于并行编程:

在并行编程中,你仍然会分解工作或任务,但是关键的区别在于你为每个工作块启动了新的线程

总结如下:

asynchronous调用将使用已被系统使用的线程,并行编程则要求开发人员打破所需的工作,spinup和teardown线程

我的基本理解是:

asynchronous编程解决了等待昂贵的操作完成之前,你可以做任何事情的问题。 如果在等待手术完成的时候可以完成其他工作,那么这是件好事。 例如:保持UI运行,并从Web服务检索更多的数据。

并行编程是相关的,但更关心的是将一个大的任务分解成可以同时计算的更小的块。 然后可以组合小块的结果来产生总体结果。 例如:射线追踪,其中各个像素的颜色基本上是独立的。

这可能比这更复杂,但我认为这是基本的区别。

我倾向于想到这些不同之处:

asynchronous:走开,完成这个任务,当你完成回来,告诉我,并带来结果。 与此同时,我还会继续做其他事情。

平行:我想让你做这个任务。 如果它更容易,让一些人来帮助。 这是紧急的,所以我会在这里等到你回来的结果。 直到你回来,我什么也做不了。

当然,一个asynchronous任务可能会利用并行性,但至less在我看来,这种区别在于是否在执行操作的时候与其他事物进行区分,或者在结果进入之前是否完全停止。

这是执行顺序的问题。

如果A和B是asynchronous的,那么当A的子部分就B的子部分发生的时候,我不能事先做出预测。

如果A与B并行,那么A中的事物与B中的事物同时发生。但是,仍然可以定义执行的顺序。

也许困难在于asynchronous这个词是不明确的。

当我告诉我的pipe家跑到商店买更多的葡萄酒和奶酪时,我会执行一个asynchronous的任务,然后忘掉他并且继续写我的小说,直到他再次敲门。 平行主义在这里发生,但是pipe家和我从事的是根本不同的任务和不同的社会阶层,所以我们在这里不应用这个标签。

当我的每个女佣都在洗别的窗户时,我的女佣队伍正在并行工作。

我的赛车支持团队是asynchronous并行的,因为每个团队都在使用不同的轮胎,他们不需要彼此沟通或在他们工作时pipe理共享资源。

我的足球(又名足球)团队并行工作,因为每个玩家都独立处理关于该领域的信息并且在其上移动,但是他们并不完全asynchronous,因为他们必须沟通和响应他人的沟通。

我的游行乐队也是平行的,因为每个玩家都会读取音乐并控制他们的乐器,但是他们是高度同步的:他们彼此玩耍和游行。

一个凸轮式的加特林枪可以被认为是平行的,但是一切都是100%同步的,所以就好像一个过程正在向前进。

为什么是asynchronous?

随着今天的应用越来越多的连接和潜在的长时间运行的任务或阻塞操作,如networkingI / O或数据库操作。因此,隐藏这些操作的延迟是非常重要的,通过在后台启动它们并返回到用户界面尽可能迅速。 这里是asynchronous进入图片, 响应

为什么要并行编程

随着今天的数据集越来越大,计算越来越复杂。 所以减less这些CPU绑定操作的执行时间非常重要,在这种情况下,将工作负载分成块,然后同时执行这些块。 我们可以称之为“并行”。 显然这将给我们的应用程序提供高性能

asynchronous:在后台运行一个方法或任务,没有阻塞。 可能不必在单独的线程上运行。 使用上下文切换/时间调度。

并行任务:每个任务并行运行。 不使用上下文切换/时间安排。

我来这里对这两个概念相当舒服,但对我来说还不清楚。

通过阅读一些答案后,我想我有一个正确和有用的比喻来描述差异。

如果你把你自己的代码作为单独的,但有序的扑克牌(如果我正在解释老派打卡的工作方式,请阻止我),那么对于每一个单独的程序,你都将拥有一堆独特的牌(不要复制&粘贴!)和正常运行代码正常和asynchronous之间的区别取决于您是否在意。

当你运行代码时,你需要向操作系统提交一组单一的操作(你的编译器或者解释器把你的“高级”代码打碎)传递给处理器。 使用一个处理器,任何时候只能执行一行代码。 因此,为了完成同时运行多个进程的错觉,操作系统使用一种技术,一次只能从一个给定的进程向处理器发送几行代码,根据它如何看待所有进程适合。 其结果是多个进程向最终用户显示进度,这似乎是同时进行的。

对于我们的隐喻来说,关系是操作系统在把它们发送给处理器之前总是将它们洗牌。 如果你的堆栈不依赖于另外一个堆栈,你不会注意到当另一个堆栈变为活动状态时,你的堆栈停止了select。 所以,如果你不在乎,这并不重要。

但是,如果你关心的话(例如,有多个进程或者一堆卡片,这些进程是互相依赖的),那么操作系统的混洗就会搞砸了你的结果。

编写asynchronous代码需要处理执行顺序之间的依赖关系,而不pipesorting结果如何。 这就是为什么使用像“回叫”的结构。 他们对处理器说:“接下来要做的就是告诉另一个堆栈我们做了什么”。 通过使用这些工具,可以确保在其他堆栈得到通知之前,允许操作系统运行指令。 (“如果called_back == false:发送(no_operation)” – 不知道这实际上是如何实现,但逻辑上我认为是一致的)

对于并行进程,区别在于你有两个不关心对方的堆栈,两个工人来处理它们。 在一天结束的时候,你可能需要结合两个堆栈的结果,这将是一个同步的问题,但为了执行,你不会在乎。

不知道这是否有帮助,但我总是发现多个解释有帮助。 另请注意,asynchronous执行不限于个人计算机及其处理器。 一般来说,它涉及时间,或者(更一般地说)事件的顺序。 因此,如果将相关堆栈A发送到networking节点X及其耦合堆栈B到Y,则正确的asynchronous代码应该能够考虑到在笔记本电脑上本地运行的情况。

asynchronous :在别的地方自己做,当你完成(callback)时通知我。 当时我可以继续做我的事情。

在这里输入图像说明

平行按照你的愿望雇佣许多人(线程),并把工作分配给他们,以便更快地完成工作,并在完成时让我知道(callback)。 到时候我可能会继续做我的其他东西。

在这里输入图像说明

并行性的主要区别主要取决于硬件。