Skip to content

Rust 异步运行时:Future、poll 与 Tokio ​

前置:所有权、Result、线程版 Send/Sync。本系列四篇依次是本篇、任务所有权、完整工程、诊断。异步是组织等待和并发的方式,不保证任意 CPU 计算更快。本批示例未执行,下面的行为都是接口契约、人工推导和未来自跑预期。

Future 与 poll ​

Rust Future与poll的关系是状态机与推进操作:调用 async fn 得到 Future,函数体尚未因此全部执行;执行器用 poll 推进到 Ready 或 Pending。await 使当前 Future 在等待子 Future 时保存必要状态,并不自动创建新线程。若子 Future 已就绪,await 可以直接继续,所以“有 await 就一定切换任务”并不成立。

poll 接收 Pin<&mut Self> 与 Context,返回 Poll<Output>。Pin 支持具有地址稳定要求的状态机,不是“把所有数据搬到堆上”的同义词;普通 async 调用不需要业务代码手写 unsafe。Ready 交付结果;Pending 表示当前未完成,不允许把 poll 写成一直忙等直到完成。Future 完成后不应再次自行轮询;运行时会管理这一协议。标准库 Future 是这一层的定义。

Waker 的通知协议 ​

Rust Waker唤醒协议连接通知与重新调度:返回 Pending 的 Future 必须安排在可推进时通过当前 Context 的 Waker 唤醒任务;wake 不是计算结果,也不保证立刻执行一次 poll。多次唤醒可合并,唤醒后再轮询仍可能 Pending。外部事件和状态检查之间存在竞态,手写 Future 不能只先检查布尔值、再存 waker 而忽视丢失唤醒。

例如有界通道接收不到消息时注册接收任务,发送者入队后通知;执行器随后 poll 才能取到值。资源是否就绪由资源的协议决定,执行器不靠不停扫描所有 Future 代替通知。初学者优先使用 Tokio 的通道和 I/O Future,先理解为什么等待不占着工作线程,再考虑自己实现 Future。中文 Book 的 Future 说明 可与英文定义对读,它是社区翻译,不冒称官方中文规范。

执行器与资源驱动 ​

Rust执行器与资源驱动分别负责调度和事件:执行器决定哪些任务需要 poll,资源驱动把 I/O 就绪或定时器到期转成唤醒;Tokio Runtime 将这些组件组合起来。Rust 标准库提供 Future 协议,但没有替每个应用自动启动 Tokio。async fn 因而不等同于安装了网络事件循环。

本工程只有有限数值计算与 yield,不创建网络或定时器;Builder 不启用时间和 I/O 驱动是刻意的。以后增加 sleep 需要 time 特性和 enable_time,增加 Tokio 网络需要相应 net 特性和 I/O 驱动;不能只复制 async 关键字。Tokio 的 feature 开关与 Builder 开关是两个检查点,一个控制编译能力,一个控制运行时资源。核对 Tokio 1.48.0 runtime。

单线程与多线程 ​

Rust单线程与多线程运行时决定任务调度位置:current_thread 在进入 block_on 的线程推进异步任务,multi_thread 用工作线程池调度;并发表示多个工作在生命周期上重叠,并行才表示同一时刻在不同处理器执行。单线程也可并发等待,但一个长时间不返回的 poll 会拖住全部任务。

本工程用两条 worker 线程,limit 单独限制已提交且未回收任务数;worker 数不是业务并发额度。yield_now 是合作让出机会,不保证另一个任务先运行,也不是精确公平或耗时承诺。有限工作片段和任务数量上限使调度具备合理前提;CPU 密集生产负载还需要独立容量规划。current_thread 并不会改变 tokio::spawn 的 Send 要求,处理非 Send 状态见下一篇 LocalSet。

练习 ​

解释以下三种情况:① async fn 创建后从未 await;② 轮询一个永远循环而不返回的 Future;③ 两个任务每次 yield 后恰好还是同一任务继续。分别判断是否违背异步协议,区分“合法但未执行”和“阻塞调度”。

参考解法 ​

① Future 可被直接丢弃,函数体不因此执行;若需要工作发生,必须有推进者。② poll 不应阻塞直到结果出现,长循环破坏合作调度前提。③ 允许;yield 不是轮流执行协议,不能据此断言结果到达顺序。

来源与范围 ​

2026-10-17公开核对上文具体链接,以及 Rust 官方中文学习入口。示例固定 Tokio 1.48.0,并未宣称它是最新版本。本篇不实现自制执行器、不展示伪网络请求;完整源码和静态验证范围在实践页。

继续阅读