在处理此主题时,需要定义许多术语。
异步 - 在不阻塞的情况下继续工作的能力(即,在开始另一个任务之前不等待任务完成)。异步任务通常使用多线程来完成,但不一定必须这样做。
多线程 - 在一个进程中有多个不同的执行“线程”。通常,您的程序中会发生许多线程,而您甚至都不知道。
多处理 - 作为多线程,但当您的代码对在多个处理器或内核上同时执行敏感时。
并发 - 这个术语往往以多种方式使用,但意味着“同时”发生的不止一件事情。它可能意味着任务切换(如在线程之间交换一个内核/处理器)或字面并发(多个内核同时运行代码)。在编程中,它通常是指程序能够可靠地处理并发任务(例如,一个网站一次处理多个用户,我们会说这是“并发安全”或“并发感知”)。
异步编程就是不等待工作完成,除非你没有其他工作要做。即便如此,您通常不是在等待工作完成,而是在等待更多工作的到来。
所以这样想。你带你的配偶/伴侣出去吃饭,你正在排队等女主人让你坐下。当每个人进来时,她都会和他们打招呼,找到一张桌子,然后把他们带回桌子,拿下他们的酒单,提交,然后回到前台迎接下一个人。那是同步工作。
现在,你去另一家餐厅,这一次,女主人留在原地,在每个人进来时记下他们的名字,当有桌子可用时,她让你的服务员为你安排座位,而她则留在办公桌前检查是否有新桌子开放,以及让新客户走进来。这是异步的。
异步编程通常通过多线程/处理完成,但不一定需要它。例如,有时可以使用轮询机制来实现异步,其中程序正在等待用户输入,但它会继续做一些工作,定期检查用户是否输入了任何内容。这不需要任何多线程(从技术上讲,大多数操作系统中的用户输入在它自己的进程或线程上运行,因此最终可以考虑,但从应用程序的角度来看它不需要),但被认为是异步的。
了解异步编程的关键是它不会使程序运行得更快。它可能使程序响应更快,并且它可能(通过有效响应和管理多线程)使程序更快地完成多个任务(或在同一时间段内执行更多工作),但它实际上并没有运行得更快比并排跑的两个奥运短跑选手完成比赛的速度更快。任何 1 个任务仍将花费相同的时间。
异步编程可以在同一时间段内完成更多工作,假设有多余的 CPU 周期或 IO 带宽来完成它,因为它更有效地使用资源,但它有许多与多线程相同的限制。使用两个跑步者的类比,如果你给两个跑步者每人一个包裹,那么你可以在大致相同的时间内交付 2 个包装商,你可以交付 1 个。但是你不能以两倍的速度交付 1 个包裹。这就像9个女人不能在1个月内生孩子一样。
同样,如果您给两个跑步者每人一个包裹,但他们必须使用只能容纳一个人的电梯。除非有两个电梯,否则您不能在同一时间范围内交付两个包裹。这就像 I/O 带宽限制。
而且,当然,如果你只有一个跑步者,你是否尝试使用异步并不重要,交付 2 个包裹仍然需要 2 倍的时间(实际上是 4 倍,因为跑步者必须跑步返回,等待包裹被签收等),尽管异步可以稍微提高输入队列的性能(接受包裹进行交付的人,然后将包裹扔到传送带上让跑步者捡起) .