48·异步编程高级

Future trait 深入

Future trait 深入

学习目标

  1. 理解 Future 的 poll 机制
  2. 理解 Waker 的作用
  3. 掌握手写 Future

核心概念

Future trait

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

trait Future {
    type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

poll 机制

// 执行器不断调用 poll:
// 1. 返回 Poll::Ready(value) → 完成
// 2. 返回 Poll::Pending → 注册 Waker,稍后通知

// 流程:
// 执行器 → poll() → Pending → 注册 Waker
//                    ↓
//              IO 就绪 → Waker 通知执行器
//                    ↓
//              执行器 → poll() → Ready(value)

手写 Future

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::{Duration, Instant};

struct Delay {
    when: Instant,
}

impl Delay {
    fn new(duration: Duration) -> Self {
        Delay { when: Instant::now() + duration }
    }
}

impl Future for Delay {
    type Output = ();

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
        if Instant::now() >= self.when {
            Poll::Ready(())
        } else {
            // 注册 waker,实际中应该让 IO 操作完成后调用 wake()
            cx.waker().wake_by_ref();
            Poll::Pending
        }
    }
}

async 块的 Future

// async { expr } 会被编译器转换为实现了 Future 的匿名类型
let future = async {
    1 + 2
};
// 等价于手写的 Future,状态机自动管理

小结

概念说明
poll驱动 Future 的方法
Poll::Ready完成
Poll::Pending未完成
Waker通知执行器的机制
Pin防止值被移动

练习编辑器

rust
Loading...