
Rust async 状态机揭秘:Future、poll、Waker 到底怎么工作?
你的 Rust async 代码是个“骗子”:我把它的状态机底裤给扒了! 你有没有过这样的经历:你写了一个 async 函数,满心欢喜地调用了它,然后……程序“啪”一下就结束了,啥也没发生。 你盯着屏幕,陷入沉思:我的代码呢?我的 println! 呢?难道我刚才运行了个寂寞? 别慌,你不是一个人。欢迎来到 Rust async 的世界,这里的第一条规则就是:你眼睛看到的,不一定是真的。 async/await 是 Rust 并发编程的王牌,它能让你用看似同步的代码,写出性能炸裂的非阻塞程序,轻松应对成千上万的网络连接。但在这优雅的语法糖背后,藏着一个精妙绝伦、却也让无数新手迷惑的底层机制。 今天,我就带你潜入 Rust 的“引擎室”,把 Future、.poll() 和状态机这几个核心部件给你安排得明明白白。 第一幕:天大的误会 —— async fn 根本不会立即执行 让我们从这个最基础的“骗局”开始。你写了这么一个函数: async fn say_hello() { println!("Hello, from the future!"); } 然后你调用它: fn main() { say_hello(); // 程序结束,什么都不会打印 } 为什么?因为调用一个 async 函数,并不会执行它里面的代码。它只会返回一个东西,叫做 Future。 什么是 Future? 你可以把它想象成一张“未来才会兑现的承诺券”。 这张券本身什么都不是,你拿着它,它不会自动变成奖品。say_hello() 函数返回的就是这么一张承诺券,上面写着:“我承诺,未来某个时候会打印一行字”。 你的 main 函数拿到了这张券,然后就把它扔了,程序自然就结束了。 记住:async 函数返回的是一个“计划”,而不是一个“结果”。 第二幕:引擎启动 —— Executor 和 .await 的登场 那么,怎么才能让这张“承诺券”兑现呢? 你需要一个“执行器”(Executor),比如大名鼎鼎的 tokio 或 async-std。 你可以把执行器想象成一个精力无限的厨房总管。 ...