1. 一个例子
use futures::executor::block_on;
use std::future::Future;
#[tokio::main]
async fn main() {
let name1 = "Tyr".to_string();
say_hello1(&name1).await;
// Future 除了可以用 await 来执行外,还可以直接用 executor 执行
block_on(say_hello1(&name1));
}
async fn say_hello1(name: &str) -> usize {
println!("Hello {}", name);
42
}
rust构建了一层语法糖,封装协程
- async fn say_hello1 的async关键字封装了Future
- say_hello1(&name1).await,触发了Future执行
- block_on是Future执行器
2. Future机制
Future的定义如下,底层的原理就是Reactor机制
pub trait Future {
type Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
pub struct Context<'a> {
waker: &'a Waker,
_marker: PhantomData<fn(&'a ()) -> &'a ()>,
}
调度器excutor通过poll方法来让 Future 继续往下执行,如果 poll 方法返回 Poll::Pending,就阻塞 Future,直到 reactor 收到了某个事件,然后调用 Waker.wake() 把 Future 唤醒
3. Future使用场景
- 异步任务适合用来处理IO密集型任务,要避免计算密集型任务。
- 在使用 Mutex 等同步原语时,要注意标准库的 MutexGuard 无法跨越 .await,所以,此时要使用对异步友好的 Mutex,如 tokio::sync::Mutex;
- 如果要在线程和异步任务间同步,可以使用 channel。