2

我总是想知道:假设在一家商店里,一位主管正在为客户 A 服务。现在,同一位主管转向客户 B 并服务一段时间,然后再为 C 服务,然后再为 A 服务,依此类推。

现在,在这里,执行的总时间是相同的,即 A+B+C 时间 = A 的时间 + B 的时间 + C 的单独时间。

我看不出在这个时间方面有什么好的理由。然而,为什么异步被赋予了至关重要的意义?特别是在电子产品开发软件方面?我因为异步编程中的一个愚蠢问题而失去了面试。:(

有人可以解释一下吗?我知道异步编程的书定义,但实际上我想在可以应用它的地方感到满意。

4

5 回答 5

3

在处理此主题时,需要定义许多术语。

异步 - 在不阻塞的情况下继续工作的能力(即,在开始另一个任务之前不等待任务完成)。异步任务通常使用多线程来完成,但不一定必须这样做。

多线程 - 在一个进程中有多个不同的执行“线程”。通常,您的程序中会发生许多线程,而您甚至都不知道。

多处理 - 作为多线程,但当您的代码对在多个处理器或内核上同时执行敏感时。

并发 - 这个术语往往以多种方式使用,但意味着“同时”发生的不止一件事情。它可能意味着任务切换(如在线程之间交换一个内核/处理器)或字面并发(多个内核同时运行代码)。在编程中,它通常是指程序能够可靠地处理并发任务(例如,一个网站一次处理多个用户,我们会说这是“并发安全”或“并发感知”)。

异步编程就是不等待工作完成,除非你没有其他工作要做。即便如此,您通常不是在等待工作完成,而是在等待更多工作的到来。

所以这样想。你带你的配偶/伴侣出去吃饭,你正在排队等女主人让你坐下。当每个人进来时,她都会和他们打招呼,找到一张桌子,然后把他们带回桌子,拿下他们的酒单,提交,然后回到前台迎接下一个人。那是同步工作。

现在,你去另一家餐厅,这一次,女主人留在原地,在每个人进来时记下他们的名字,当有桌子可用时,她让你的服务员为你安排座位,而她则留在办公桌前检查是否有新桌子开放,以及让新客户走进来。这是异步的。

异步编程通常通过多线程/处理完成,但不一定需要它。例如,有时可以使用轮询机制来实现异步,其中程序正在等待用户输入,但它会继续做一些工作,定期检查用户是否输入了任何内容。这不需要任何多线程(从技术上讲,大多数操作系统中的用户输入在它自己的进程或线程上运行,因此最终可以考虑,但从应用程序的角度来看它不需要),但被认为是异步的。

了解异步编程的关键是它不会使程序运行得更快。它可能使程序响应更快,并且它可能(通过有效响应和管理多线程)使程序更快地完成多个任务(或在同一时间段内执行更多工作),但它实际上并没有运行得更快比并排跑的两个奥运短跑选手完成比赛的速度更快。任何 1 个任务仍将花费相同的时间。

异步编程可以在同一时间段内完成更多工作,假设有多余的 CPU 周期或 IO 带宽来完成它,因为它更有效地使用资源,但它有许多与多线程相同的限制。使用两个跑步者的类比,如果你给两个跑步者每人一个包裹,那么你可以在大致相同的时间内交付 2 个包装商,你可以交付 1 个。但是你不能以两倍的速度交付 1 个包裹。这就像9个女人不能在1个月内生孩子一样。

同样,如果您给两个跑步者每人一个包裹,但他们必须使用只能容纳一个人的电梯。除非有两个电梯,否则您不能在同一时间范围内交付两个包裹。这就像 I/O 带宽限制。

而且,当然,如果你只有一个跑步者,你是否尝试使用异步并不重要,交付 2 个包裹仍然需要 2 倍的时间(实际上是 4 倍,因为跑步者必须跑步返回,等待包裹被签收等),尽管异步可以稍微提高输入队列的性能(接受包裹进行交付的人,然后将包裹扔到传送带上让跑步者捡起) .

于 2013-07-14T19:06:22.940 回答
2

在您的示例中,同步编程是客户端 A 下订单并等待店员完成订单,然后客户端 B 下订单并等待完成等等。由于不止一名职员,客户仍在等待完成。

异步是当客户 A 下订单时,店员说“好的,将完成,你现在可以走了”,客户 A立即满意地离开,店员要求其他人完成工作,然后立即转向客户 B,依此类推.

总体执行时间相似,但等待时间更短,因为任务会立即确认并稍后执行,可能由其他人(另一个线程、线程池、队列)执行。

于 2013-07-14T17:52:42.037 回答
2

异步编程提供了两个主要好处:

  1. (在客户端)响应性。您可以保持对用户的响应,而不是阻止 UI 线程等待某些操作完成。
  2. (在服务器端)可扩展性。您可以在等待时让它为其他请求工作,而不是阻塞等待某个操作完成的线程。

此外,异步编程支持一种与多线程无关的并发形式。例如,您可以轻松启动多个操作,然后(异步)等待它们全部完成。与传统的多线程(并行处理)相比,这更容易、更不容易出错并且更具可扩展性。

于 2013-07-14T17:59:09.663 回答
1

好。假设您从 Internet 下载了两个文件。您有 10 兆字节/秒的下载容量。您(从不同的服务器)下载的两个文件的上传容量分别为 1 Mb / s。什么是最好的,先下载文件 A,然后下载文件 B,或者同时下载文件 A 和 B?即使 CPU 处理数据的总时间相同,您仍然会更快地完成。

尤其是 IO-bound 操作有很多等待时间。那段时间花在做其他事情上比只是等待更有意义。

或者,如果您更喜欢客户场景。假设客户购买的是与您的出租车一起旅行。将具有线程功能的汽车一分为二并同时驾驶两个客户,而不是先驾驶一辆,然后驾驶另一辆,速度要快得多。即使拆分驱动程序必须完成相同数量的总工作。

于 2013-07-14T17:44:02.807 回答
1

举个你自己的例子吧,想象一下每个客户都必须暂停 5 秒才能取出钱、签署一些东西、阅读其他东西等等。

如果您的店员在等待客户,他会浪费很多时间,而他可以在这 5 秒内切换到另一个客户并开始/继续另一笔交易。

异步处理是一件好事,因为它允许回收时间,否则会因等待其他事情而浪费。在编程中,那些其他的东西通常是磁盘/网络 I/O 或长时间的后台任务。

于 2013-07-14T17:46:16.700 回答