pub trait Wake {
// Required method
fn wake(self: Arc<Self>);
// Provided method
fn wake_by_ref(self: &Arc<Self>) { ... }
}
Expand description
在执行程序上唤醒任务的实现。
一个可以用于创建 Waker
的 trait。
执行者可以定义此 trait 的实现,并使用它来构造一个 Waker 以传递给在该执行者上执行的任务。
这个 trait 是构建 RawWaker
的一种内存安全且符合人体工程学的替代方案。
它支持通用执行程序设计,其中用于唤醒任务的数据存储在 Arc
中。
某些执行程序 (尤其是嵌入式系统的执行程序) 无法使用此 API,这就是为什么存在 RawWaker
来替代这些系统的原因。
Examples
一个基本的 block_on
函数,它采用 future 并在当前线程上运行该函数以使其完成。
Note: 本示例以正确性为代价。
为了防止死锁,生产级实现也将需要处理对 thread::unpark
的中间调用以及嵌套调用。
use std::future::Future;
use std::sync::Arc;
use std::task::{Context, Poll, Wake};
use std::thread::{self, Thread};
use core::pin::pin;
/// 一个在调用时唤醒当前线程的唤醒器。
struct ThreadWaker(Thread);
impl Wake for ThreadWaker {
fn wake(self: Arc<Self>) {
self.0.unpark();
}
}
/// 在当前线程上运行 future 以完成操作。
fn block_on<T>(fut: impl Future<Output = T>) -> T {
// 固定 future,以便可以对其进行轮询。
let mut fut = pin!(fut);
// 创建一个要传递给 future 的新上下文。
let t = thread::current();
let waker = Arc::new(ThreadWaker(t)).into();
let mut cx = Context::from_waker(&waker);
// 运行 future 直到完成操作。
loop {
match fut.as_mut().poll(&mut cx) {
Poll::Ready(res) => return res,
Poll::Pending => thread::park(),
}
}
}
block_on(async {
println!("Hi from inside a future!");
});
Run