< 返回版块

Mike Tang 发表于 2026-03-19 14:00

在 Rust 中实现自定义 Future

这段代码演示了如何在 Rust 中手动实现一个自定义的 Future,通过创建一个简单的延迟(Delay)future 来说明核心概念。

主要知识点

1. Pin<&mut Self> 的作用

  • 保证结构体在内存中不会被移动
  • 本例中 Delay 只包含 InstantDuration(都是 Unpin 类型),编译器自动实现了 Unpin,因此固定(pinning)操作实际上是空操作
  • 如果结构体包含自引用借用(如手写的异步状态机),固定会防止首次轮询后的移动,避免借用失效

2. Poll::Pending vs Poll::Ready

  • 返回 Poll::Pending 告诉执行器"我还没完成,稍后唤醒我"
  • 返回 Poll::Ready(()) 表示 future 已完成

3. cx.waker() 唤醒机制

  • 这是安排重新轮询的关键机制
  • 必须调用 wake(),否则执行器永远不会再次轮询,future 会挂起
  • 生产环境的计时器会向反应器(reactor)注册;本例为简化直接请求立即重新轮询

代码实现

  • Delay 结构体:包含一个截止时间(deadline)
  • poll 方法:检查当前时间是否达到截止时间
    • 已到达 → 返回 Poll::Ready(())
    • 未到达 → 调用 cx.waker().wake_by_ref() 并返回 Poll::Pending
  • 使用示例:在异步主函数中等待 10 毫秒,验证实际经过的时间

注意事项

这是一个教学示例,采用忙轮询(busy-polling)方式,实际应用中应使用定时器轮(timer wheel)或反应器模式以提高效率。

https://rust-lang-nursery.github.io/rust-cookbook/concurrency/custom_future.html

Rust Actor 模式实现驾驶员位置追踪系统

这是一个使用 Tokio 异步运行时实现的 Actor 模式示例,用于管理驾驶员位置信息。

核心组件

Message 枚举

  • 定义了 Actor 接收的命令类型
  • UpdateLocation: 更新驾驶员位置(包含驾驶员ID、经纬度)
  • GetDriverStatus: 查询驾驶员状态(通过 oneshot 通道返回结果)

DriverStatus 结构体

  • 存储驾驶员状态信息:ID、经纬度坐标、更新次数

DriverActor(Actor 实体)

  • 拥有数据的所有权,运行在独立的任务中
  • 使用 HashMap 存储所有驾驶员状态
  • 无需 Arc<Mutex>,因为只有一个任务访问数据
  • run() 方法:循环接收并处理消息
  • handle_message() 方法:处理具体的消息逻辑

DriverHandle(句柄)

  • 可克隆的句柄,持有 mpsc::Sender
  • 在应用程序中传递和共享
  • 提供异步方法:
    • update_location(): 发送位置更新命令
    • get_driver_status(): 查询驾驶员状态并等待响应

关键特性

  • 并发安全:通过消息传递避免共享内存,无需显式锁
  • 可扩展:Handle 可克隆并发送到多个任务
  • 异步通信:使用 mpsc 通道进行命令发送,oneshot 通道获取响应
  • 简洁的 API:外部代码通过 Handle 与 Actor 交互,隐藏实现细节

示例执行流程

主函数演示了多任务并发更新驾驶员位置,然后查询不同驾驶员的状态,包括不存在的驾驶员(返回 None)。

https://rust-lang-nursery.github.io/rust-cookbook/concurrency/actor.html

--

From 日报小组 Mike

社区学习交流平台订阅:

评论区

写评论

还没有评论

1 共 0 条评论, 1 页