如何阐明异步编程和并行编程的区别?

许多平台提倡将异步和并行作为提高响应性的手段。我大体上理解这种差异,但是经常发现很难在自己的头脑中清晰地表达出来,对于其他人也是如此。

我是一个普通的程序员,经常使用异步和回调。

但是我觉得它们很容易混为一谈,特别是在语言设计层面。希望能够清楚地描述它们之间的关系(或者不关系) ,以及每种关系最适用的程序类别。

57168 次浏览

本文很好地解释了它: http://urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

它有关于异步编程的内容:

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

关于并行编程:

在并行编程中,您仍然需要分解工作或任务,但关键的区别在于,您需要为每个工作块生成新的线程

总结一下:

异步调用 将使用 系统已经在使用的线程,而 并行程序设计需要 开发人员分解所需的工作、旋转和拆卸线程

我的基本理解是:

异步编程解决了等待代价高昂的操作完成之后才能进行其他操作的问题。如果你可以在等待手术完成的同时完成其他事情,那么这是一件好事。示例: 在从 Web 服务检索更多数据时保持 UI 运行。

并行编程是相关的,但它更关注于将大型任务分解成可以同时计算的小块。然后,可以将较小块的结果组合起来以产生总体结果。例如: 光线跟踪,其中每个像素的颜色基本上是独立的。

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

当您异步运行某些内容时,这意味着它是非阻塞的,您可以执行它,而不必等待它完成并继续处理其他事情。并行意味着同时并行地运行多个事物。当您可以将任务分成独立的工作部分时,并行工作很有效。

以渲染3D 动画的框架为例。渲染动画需要很长的时间,所以如果你要从你的动画编辑软件启动渲染,你要确保它运行 异步的,这样它就不会锁定你的 UI,你可以继续做其他事情。现在,该动画的每一帧也可以被视为一个单独的任务。如果我们有多个 CPU/Core 或多台机器可用,我们可以在 平行中渲染多个帧,以加快整体工作负载。

我倾向于认为这些术语的不同之处在于:

异步: 走开去做这个任务,当你完成后回来告诉我并带来结果。与此同时,我还要处理其他事情。

平行: 我要你做这个任务。如果方便的话,找些人来帮忙。这件事很紧急,所以我会在这里等你,直到你带着结果回来。在你回来之前我什么也做不了。

当然,一个异步任务可能会使用并行性,但是区别——至少在我看来——在操作执行期间是否处理其他事情,或者是否在结果出来之前完全停止所有事情。

这是一个执行顺序的问题。

如果 A 与 B 是异步的,那么我就不能事先预测 A 的子部分相对于 B 的子部分何时发生。

如果 A 和 B 是平行的,那么 A 中的事情和 B 中的事情是同时发生的。然而,执行的顺序仍然可以被定义。

也许困难在于“异步”这个词是模棱两可的。

当我告诉管家去商店买更多的葡萄酒和奶酪,然后忘记他,继续写我的小说,直到他再次敲书房的门时,我执行了一个异步任务。平行论在这里发生,但是管家和我从事的是完全不同的任务,属于不同的社会阶层,所以我们在这里不使用这个标签。

我的女佣团队正在并行工作,每个人都在清洗不同的窗户。

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

我的足球队(又名足球队)做平行工作,因为每个球员独立处理有关球场的信息,并在球场上移动,但他们不是完全异步的,因为他们必须沟通和回应其他人的沟通。

我的军乐队也是平行的,因为每个演奏者读音乐和控制他们的乐器,但他们是高度同步的: 他们演奏和行军的时间对方。

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

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

Async 复试通常是表示并发性的一种方式(工具或机制) ,即一组可能相互通信并共享资源的实体。 在异步或回调通信的情况下是隐式的,而资源共享是可选的(考虑 RMI,其中结果是在远程计算机中计算的)。 正如正确指出的那样,这通常是在考虑到响应性的情况下进行的; 不要等待很长的 潜伏期事件。

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

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

计算模型是一种并发模型,当它能够将系统表示为由独立的自治组件组成、可能相互通信的时候。平行主义就像古埃及,在那里法老决定和奴隶的工作。并发就像现代意大利,每个人都做他们想做的事情,都使用移动电话。

总之,并行编程在某种程度上是并发的一种特殊情况,其中不同的实体协作以获得高性能和吞吐量(通常)。

异步和回调只是一种允许程序员表达并发性的机制。 考虑到众所周知的并行编程设计模式(如 master/worker 或 map/reduce)是由使用这种低级机制(异步)实现更复杂的 集中交互的框架实现的。

异步: 在后台运行方法或任务,不会阻塞。不一定在单独的线程上运行。使用上下文切换/时间调度。

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

我来到这里,对这两个概念相当熟悉,但对它们有一些不清楚的地方。

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

如果你认为你的每一行代码都是独立但有序的扑克牌(如果我在解释老式穿孔卡片的工作原理,请打断我) ,那么对于每一个独立的程序,你都会有一堆独特的卡片(不要复制和粘贴正常运行代码和异步运行代码时通常发生的事情之间的区别取决于您是否关心。

当你运行代码的时候,你给操作系统一组单独的操作(你的编译器或者解释器将你的“高级”代码分解进去)传递给处理器。使用一个处理器,任何时候只能执行一行代码。因此,为了实现同时运行多个进程的错觉,操作系统使用了一种技术,每次只向处理器发送给定进程的几行信息,并根据它认为合适的方式在所有进程之间切换。其结果是多个进程同时向最终用户显示进度。

对于我们的比喻,关系是操作系统总是在将卡发送到处理器之前洗牌。如果你的牌堆不依赖于另一个牌堆,你不会注意到当另一个牌堆变得活跃时,你的牌堆停止被选中。所以如果你不在乎,那也没关系。

然而,如果你真的在意(例如,有多个进程-或堆叠的卡片-确实相互依赖) ,那么操作系统的洗牌会搞砸你的结果。

编写异步代码需要处理执行顺序之间的依赖关系,而不管最终的顺序是什么。这就是为什么使用“回调”这样的结构。他们对处理器说,“接下来要做的就是告诉另一个堆栈我们做了什么”。通过使用这些工具,您可以确保其他堆栈在允许操作系统运行更多指令之前得到通知。(“ If call _ back = = false: send (no _ operation)”——不确定这是否是它实现的方式,但从逻辑上讲,我认为它是一致的。)

对于并行流程,区别在于您有两个不关心彼此的堆栈和两个处理它们的工作者。在一天结束时,您可能需要合并来自两个堆栈的结果,这将是一个同步性问题,但是对于执行,您不再关心这个问题。

不知道这是否有帮助,但是,我总是发现多种解释有帮助。另外,请注意,异步执行不限于单个计算机及其处理器。一般来说,它处理的是时间,或者(更一般地说)事件的顺序。因此,如果您将依赖堆栈 A 发送到网络节点 X,并将其耦合堆栈 B 发送到 Y,那么正确的异步代码应该能够解释这种情况,就好像它在您的笔记本电脑上本地运行一样。

为什么是异步的?

随着今天的应用程序越来越多的连接,也有潜在的 长时间运行的任务或阻塞操作,如网络 I/O 或数据库操作。因此,通过在后台启动这些操作并尽快返回到用户界面来隐藏这些操作的延迟是非常重要的。在这里异步进入图片,回应

为什么是并行编程?

随着今天的数据集越来越大,计算越来越复杂。因此,减少这些 CPU 绑定操作的执行时间非常重要,在本例中,方法是将工作负载划分为块,然后同时执行这些块。我们可以称之为“平行”。 显然,它将给我们的应用程序高 表演

在其他地方通过 你自己完成此操作,并在完成(回调)时通知我。等我能继续做我的事。

enter image description here

并行 : 你想雇多少人就雇多少人并分割工作给他们完成 更快,并让我知道(回调)当你完成。当我 也许吧继续做我的其他事情的时候。

enter image description here

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

异步的 假设你是客户的联系人,你需要响应客户的要求,也就是说,你需要分享客户的状态、操作的复杂性、需要的资源等等。现在您有一个耗时的操作要做,因此不能采取这一点,因为您需要响应客户端24/7。因此,您可以将这个耗时的操作委托给其他人,这样您就可以做出响应。这是异步的。

并行编程 假设您有一个任务要从一个文本文件中读取100行,而读取一行需要1秒钟。因此,读取文本文件需要100秒。现在您担心客户端必须等待100秒才能完成操作。因此,您需要创建另外9个克隆,并让它们每个从文本文件中读取10行。现在读100行只需要10秒钟。因此,你有更好的表现。

总之,异步编码是为了实现响应性,并行编程是为了性能。

一般来说,只有两种方法可以让你每次做一件以上的事情。一个是 异步的另一个是 平行

从高层次上来说,它们都充分利用了异步模式,即单线程服务器可以同时服务数千个客户端(有些是 IOloop复试) ,这与流行的 NGINX服务器和著名的 巨蟒龙卷风一样。使用 ECF(异常控制跟随)来实现异步编程范型。所以异步有时并不能同时完成某些工作,但是异步可以提高性能。

平行模式总是指多线程和多处理。这可以充分利用多核处理器,真正同时做事情。

以上答案的摘要

  1. 并行计算:

解决吞吐量问题。 关注于将一个大任务分解成更小的块

是机器相关的(需要多机器/核心/CPU/处理器) ,例如: 主从,映射减少。

并行计算通常涉及一个中央控制器,它将工作分配给几个处理器

  1. 异步:

解决延迟问题 例如,“等待”的问题,等待一个昂贵的操作完成之前,你可以做其他任何事情

是线程相关的(需要多个线程)

线程(使用 Thread、 Runnable、 Execator)是在 Java 中执行异步操作的一种基本方法