Function a_async_intro

Source
pub fn a_async_intro()
Expand description

让我们先从建立异步编程模型的整体概念框架开始,先不深入细节。

Rust 提供的异步并发相比于其他语言有什么特点?

  1. Rust 语言只是提供一个零成本的异步编程抽象,而不内置运行时。
  2. 基于 Generator 实现的 Future,在 Future 基础上 提供 async/await 语法糖。本质是一个状态机。

查看 README 和其他编程语言比较的图示。

为什么需要异步?

  1. 对极致性能的追求。
  2. 对编程体验的追求。

异步编程模型发展阶段:

  1. Callback
  2. Promise/Future
  3. async/await

可在项目 README 查看回调地狱示例图。

A
+------+
|      |
|      |
|      +-------------------+
|      |                   |
|      |                   |
|      |                  Bv
+------+                +-----+
|      |                |     |
|      |                | do1 |
|      |                |     |
|      |                +-----+
|      |                |     |
|      |                | do2 |
|      |                +-+---+
|      |                  |
|      |                  |
| A    |                  |
+------+                  |
|      |                  |
|      |                  |
|      |                  |
|      | <----------------+
|      |
|      |
|      |
+------+

早期 Rust 异步写法示意:

let future = id_rpc(&my_server).and_then(|id| {
    get_row(id)
}).map(|row| {
    json::encode(row)
}).and_then(|encoded| {
    write_string(my_socket, encoded)
});

这样写会存在大量内嵌 Future,开发体验不好。

引入 async/await 之后:

let id = id_rpc(&my_server).await;
let row = get_row(id).await;
let encoded = json::encode(row);
write_string(my_socket, encoded).await;

拥有了和同步代码一致的体验。

异步任务可看作是一种绿色线程

查看 README 相关图示

可以说,异步任务的行为是模仿 线程 来抽象。

  1. 线程在进程内,异步任务在线程内。
  2. 线程可被调度切换(Linux默认抢占式),异步任务也可以被调度(协作式而非抢占式)。区别在于,异步任务只在用户态,没有线程的上下文切换开销。
  3. 线程有上下文信息,异步任务也有上下文信息。
  4. 线程间可以通信,异步任务之间也可以通信。
  5. 线程间有竞争,异步任务之间也有竞争。

整个异步编程概念,包括异步语法、异步运行时都是围绕如何建立这种「绿色线程」抽象而成的。