Rust Async: futures-timer源码解析

本文详细分析了futures-timer库的源码,包括Delay和Timer的实现,特别是Delay的时间重置逻辑和并发安全性。futures-timer使用最小堆管理定时器超时,通过并发链表实现外部交互。Delay构造、重置超时时间、析构过程以及Timer的超时处理、Future Trait实现和后台Reactor的工作原理逐一阐述,展示了Rust异步编程中Reactor与Future的交互逻辑。
摘要由CSDN通过智能技术生成

本文转载自:https://zhuanlan.zhihu.com/p/78036342

已获作者授权。

之前的文章已经提到Future,Executor和Reactor是rust异步的三个基本组件。由于io相关的Reactor涉及到操作系统的api,分析Future和Reactor 之间的交互过程往往没那么直观。futures-timer是rust官方提供一个纯用户态实现的定时器基础库,本身代码精炼,通过源码的阅读分析,可以学习到:

  1. 学习Reactor,以及和Future的交互逻辑;

  2. 学习thread::park/unpark的使用;

  3. 学习一个简单的并发链表设计;

  4. 干净地进行资源的释放;

futures-timer对外提供了Delay和Interval,以及充当Reactor角色的Timer,默认情况下会启动一个后台线程运行全局的Timer,高级用户也可以自己创建管理Timer。借助于Delay支持时间重设的特性,Interval只是Delay的一个封装,因此不做论述。

futures-timer 整体架构图

640?wx_fmt=jpeg

定时器超时的管理一般有红黑树,最小堆和旋转时间轮等数据结构。futures-timer采用的是最小堆,由Timer结构维护。由于设计一个并发的最小堆难度较大,因此 Timer结构有两部分组成,一个是管理定时器超时的堆数据结构,是Timer的私有数据,不能并发访问;一个是用于和外部交互的并发链表,作为存放外部请求的待处理队列。Timer把并发链表包装成TimerHandle,供外部创建和修改定时器。主要的数据结构定义如下:

pub struct Timer {
    inner: Arc<Inner>,
    timer_heap: Heap<HeapTimer>,
}

pub struct TimerHandle {
    inner: Weak<Inner>,
}

struct Inner {
// 保存刚创建或者更新的定时器队列,等待Timer进行处理
    list: ArcList<ScheduledTimer>,
    // Timer一般在一个死循环里,没消息时处于睡眠状态,
    // 当上面的list更新后通过这个waker把Timer唤醒让其继续干活
    waker: AtomicWaker,
}

pub struct Delay {
    state: Option<Arc<Node<ScheduledTimer>>>, // 为None时表示定时器无效
    when: Instant,
}

/// Delay和Timer之间共享的数据
struct ScheduledTimer {
    waker: AtomicWaker, // 用于Timer给Delay发送通知
// 第一个bit标记是否定时器是否已经触发,第二个bit标记是否定时器无效,
// 其他bits标记定时器被重置的次数,每重置一次加1。只有和HeapTimer里保存的一致时才会触发超时通知。
    state: AtomicUsize,

    inner: Weak<Inner>,
    at: Mutex<Option<Instant>>,
    slot: Mutex<Option&
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值