Why Async?

我们都喜欢 Rust 允许我们编写快速,安全的软件。但是为什么要编写异步代码呢?

异步代码允许我们在同一 OS 线程上,同时运行多个任务。在典型的线程应用程序中,如果您想同时下载两个不同的网页,则需要将工作分散到两个不同的线程中,如下所示:

  1. {{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites}}

这对许多应用程序都很好用 —— 毕竟,线程被设计为可以做到这一点:一次运行多个不同的任务。但是,它们也有一些限制。在不同线程之间切换,以及在线程之间共享数据的过程,涉及很多开销。即使只是一个坐着不执行任何操作的线程,也会占用宝贵的系统资源。这些就是异步代码旨在消除的成本。我们可以使用 Rust async/.await符号,重写上面的函数,这将使我们能够一次运行多个任务,而无需创建多个线程:

  1. {{#include ../../examples/01_02_why_async/src/lib.rs:get_two_sites_async}}

总体而言,与相应的线程实现相比,异步应用程序可能具有更快的速度和更少的资源。但是,这是有成本的。线程受操作系统的原生支持,并且使用它们不需要任何特殊的编程模型 —— 任何函数都可以创建一个线程,且调用那些使用线程的函数,通常与调用任何普通函数一样容易。但是,异步功能需要语言或库的特殊支持。在 Rust 中,async fn创建一个异步函数,该函数返回一个Future。要执行该函数的主体(比如:网络 API 的数据),返回的Future,必须运行(实际请求)到完成。

重要的是要记住,传统的线程应用程序可以非常高效,并且 Rust 的内存占用量小和可预测性,意味着您无需使用任何async就能取得成功。异步编程模型的增加的复杂性,并不总是值得的,并且重要的是,考虑使用更简单的线程模型,是否可以为您的应用程序,更好地提供服务。