基于 rust-lang/rust library/core/src/task 深度解析
2026-03-10 | 技术深度解读
async fn → Future 状态机 → poll(cx)
→ Poll::Ready / Pending
→ Context / Waker / Executor| 文件 | 职责 |
|---|---|
| poll.rs | Poll 及组合子 |
| ready.rs | ready! 宏 |
| wake.rs | Context / Waker / RawWaker |
trait Future {
type Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>)
-> Poll;
} pub enum Poll { Ready(T), Pending } 把“结果是否就绪”与“何时再调度”分离。
#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
pub enum Poll { Ready(T), Pending } match self {
Poll::Ready(t) => Poll::Ready(f(t)),
Poll::Pending => Poll::Pending,
}matches!(*self, Poll::Ready(_))
!self.is_ready()Poll::Ready(value)普通值可直接抬升为就绪态。
let v = ready!(child.poll(cx));Pending 就立刻向上传播,Ready 才继续。
match $e {
Poll::Ready(t) => t,
Poll::Pending => return Poll::Pending,
}| 机制 | 传播对象 |
|---|---|
| ? | Error / None |
| ready! | Poll::Pending |
pub struct Context<'a> {
waker: &'a Waker,
local_waker: &'a LocalWaker,
}代表“把当前任务重新入队”的能力句柄。
pub struct RawWaker {
data: *const (),
vtable: &'static RawWakerVTable,
}pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker| clone | wake | wake_by_ref | drop |
|---|---|---|---|
| 复制句柄 | 消费唤醒 | 借用唤醒 | 释放资源 |
clone: unsafe fn(*const ()) -> RawWaker
wake: unsafe fn(*const ())
wake_by_ref: unsafe fn(*const ())
drop: unsafe fn(*const ())若用于构造 Waker,clone / wake / wake_by_ref / drop 都必须线程安全。
RawWakerVTable::new(|_| NOOP, |_| {}, |_| {}, |_| {})async fn f() { io1().await; io2().await; }
// ≈ 枚举状态机 + poll 驱动Start → WaitingIo1 → WaitingIo2 → DoneExecutor --poll--> Future
Future --register--> IO
Future <--Pending--
IO ------wake-----> Executor
Executor --poll--> FutureExecutor creates Waker → Context → Future::poll
Pending → store Waker → event ready → wake() → requeueRawWaker = (*const (), &'static RawWakerVTable)Future::poll → Context → Waker → RawWaker → VTable → Executorawait child → poll child
Ready(v) 继续
Pending 保存现场 → wake → 再次 pollif not_ready() { return Poll::Pending; } // ❌多数 future 完成后再 poll 都是逻辑错误。