2.1 KiB
2.1 KiB
rust 异步基础
future
Future 生成三种方式
- async {}
- fn {} -> impl Future<>
- Impl Future for struct_future {}
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::time::{sleep, Duration, Sleep};
struct ReadFileFuture {
count: u8,
sp: Pin<Box<Sleep>>,
}
impl Future for ReadFileFuture {
type Output = String;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.sp.as_mut().poll(cx) {
Poll::Pending => {
println!("wait ....");
return Poll::Pending;
}
Poll::Ready(()) => {
println!("finished wait");
// return Poll::Ready("asd".to_string());
}
}
if self.count < 5 {
println!(" continue read file");
self.count = self.count + 1;
cx.waker().clone().wake();
Poll::Pending
} else {
println!("finished to read file.");
return Poll::Ready("asd".to_string());
}
}
}
fn task() -> impl Future<Output = String> {
async {
sleep(Duration::new(1, 0)).await;
println!("task finished. cost 1.");
String::from("asd")
}
}
async fn task2() {
sleep(Duration::new(2, 0)).await;
println!("task2 finished. cost 2s")
}
#[tokio::main]
async fn main() {
let d = Duration::new(4, 0);
let mut s = sleep(d);
let mut f1 = ReadFileFuture {
count: 0,
sp: Box::pin(s),
};
let h1 = tokio::spawn(f1);
let h3 = tokio::spawn(task2());
let h2 = tokio::spawn(task());
_ = tokio::join!(h1, h2, h3);
println!("main finished")
}
-
运行结果
wait .... task finished. cost 1. task2 finished. cost 2s finished wait continue read file finished wait continue read file finished wait continue read file finished wait continue read file finished wait continue read file finished wait finished to read file. main finished