本页目录
async/await 内部机制
async fn 被编译器展开成一个实现了 Future trait 的状态机——每个 .await 点是一个状态。Pin 保证 Future 在内存中不移动(自引用结构),Waker 让 executor 知道何时可以继续轮询。理解了这个展开过程,就理解了 Rust 异步的"零成本抽象"和为什么 Future 不能随意 drop。
async fn 编译后变成什么
async
编译器将 async fn 转换为实现了 Future trait 的匿名类型——一个状态机:
// 编译器生成的伪代码:
关键:每个 .await 点对应一个状态机 transition。状态机存储跨越 await 的局部变量——它们必须在 poll() 返回 Pending 后保持存活,直到下次 poll()。
Future trait
executor 循环调用 poll()。如果 Future 还没完成,返回 Poll::Pending。在返回 Pending 之前,Future 必须通过 cx.waker() 注册 waker——一个回调函数,当 Future 可能 ready 时被调用(如 IO 完成、timer 到期)。executor 收到 wake 后重新 poll()。
Pin 的作用
状态机中 State1 持有 file_content: String。如果 Future 被 move 到新地址,持有这个地址的内部指针(如果有)会悬垂。对于自引用的 Future(常见于 select! 或涉及 borrowed locals 的场景),Pin<&mut Self> 保证 Future 不会被 move——编译器不生成 memcpy 来移动 pinned 值。
简单 executor 骨架
这只是概念。真正的 executor(tokio, async-std)用 epoll/kqueue/IOCP 做 IO 多路复用,不是 busy-wait。
参考
- Rust Book: Async chapter (currently in progress for official book)
- Tokio tutorial: tokio.rs/tokio/tutorial
- async-book: rust-lang.github.io/async-book
Keywords: async, await, Future, Pin, poll, state machine, executor, waker