mynote/rust/future.md
2022-06-05 10:19:11 +08:00

108 lines
2.1 KiB
Markdown

# rust 异步基础
### future
Future 生成三种方式
- async {}
- fn {} -> impl Future<>
- Impl Future for struct_future {}
```rust
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")
}
```
- 运行结果
```bash
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
```