思维导图:定时器设计

思维导图:定时器设计

Linux 服务器经典定时器设计,根据网上的各种资料简单整理了个思维导图
请添加图片描述

单个思维导图估计也就个人看看,如果各位有兴趣可以从以下几个问题入手

  • 为啥要有专门的定时器模块
  • 定时器有啥用
  • 怎么定时
  • 关于定时器的设计与几种方案的讨论
  • 和其他模块的结合

下面是 Xmind 生成的 markdown 大纲,方便各位基于我的导图去修改

大纲

为什么需要

  • 定时事件应用
    • 心跳检测
    • 技能冷却
    • 武器冷却
    • 倒计时
    • 检测连接
  • 高效地组织并管理定时事件:把每个定时事件封装成定时器

Linux 定时机制

  • alarm/setitimer:设置超时时间,等待并捕获 SIGALARM 信号
  • 套接字超时选项
  • 多路复用超时参数 select/poll/epoll:看是否返回 0
  • timer_create:本质也是借助信号
  • timerfd_create:通过判断文件描述符来判,可以配合 IO 多路复用

和 IO 协程调度模块的结合(sylar)

  • 用 epoll_wait 来做的超时等待,毫秒级
  • IO协程调度器的idle协程会在调度器空闲时阻塞在epoll_wait上,等待IO事件发生。加入定时器功能后,epoll_wait的超时时间改用当前定时器的最小超时时间来代替。epoll_wait返回后,根据当前的绝对时间把已超时的所有定时器收集起来,执行它们的回调函数。
  • 由于epoll_wait的返回并不一定是超时引起的,也有可能是IO事件唤醒的。要再判断一下定时器有没有超时,用绝对时间就可以轻松判断啦

定时器设计与实现

成员
  • 超时时间
    • 相对时间:注册的时候一般是超时时间
    • 绝对时间:排序和确认超时的时候一般绝对时间
      • gettimeofday 获取绝对时间,依赖系统时间
      • 可能存在校时问题导致定时机制失效
        • 用小的超时步长 + 多次超时才触发 + 检测系统时间有没有往回调
        • 直接换个时间源如 clock_gettime(CLOCK_MONOTONIC_RAW) 获取系统单调时间
  • 任务回调函数
接口设计
  • 初始化
  • 添加定时器
  • 删除定时器
  • 找到最近要发生的定时任务
  • 更新检测定时器
  • 清除定时器
数据结构设计
  • 考虑:支持动态修改并维护有序,高效找到最近要发生的定时任务
  • 几种方案
    • 依赖一个固定周期触发的 tick 信号
      • 升序链表
        • 时间复杂度:添加 O(N),找最小,删除O(1)
          • tick 信号的周期对定时器性能影响比较大:周期小,精度高,CPU 负担高;周期大,精度低,CPU 负担小
          • 定时器数量比较多的时候,插入开销大
      • 时间轮:哈希思想,将定时器散列到不同的有序链表上
        • 每个链表的定时器数量的不会太常,这样插入效率也不会太拉跨;N 越大散列越均匀,插入效率越高。如果 N = 1 那就退化成升序链表了
        • 几种实现
          • 最简单的不带取模的直接一个槽为对应一个时间(纯哈希表)
            • 增删改查都O(1)
            • 可能要很多槽为,空间爆炸
          • 带取模的
            • 特征:同一条链表上每个定时器前后节点定时时间差 N * si 的整数倍(不一定是差 1 个 N);ts = (cs + (ti / si) %N
            • 先 O(1) 找到对应槽为,按有序链表操作
          • 多级时间轮(优雅)
            • 根据定时任务出发的紧急程度,分布到不同层级的时间轮中
            • 均衡了时间(简单的单时间轮差不了多少)和空间
    • 直接把超时时间当作 tick 周期
      • 基本思路:每次都取出所有定时器中超时时间最小的超时值作为一个tick,这样,一旦tick触发,超时时间最小的定时器必然到期。处理完已超时的定时器后,再从剩余的定时器中找出超时时间最小的一个,并将这个最小时间作为下一个tick,如此反复,就可以实现较为精确的定时。根据绝对时间去排序
      • 具体实现
        • 最小堆:增删O(log2N),删除O(n) 因为查找要O(n)可以配合 hash map 来辅助快速索引,查最小O(1)直接根节点
        • 红黑树:都 O(log2N),查最小就是查红黑树的最左节点
        • 其他:跳表

参考资料

《Linux高性能服务器编程》第 11 章
sylar 服务器 定时器模块

<think>好的,我需要帮用户获取关于单片机学习的思维导图。首先,用户提到了几个引用,其中引用[2]和[3]提到了C语言学习路线和嵌入式相关的思维导图,但用户需要的是更具体的单片机学习导图。我需要结合这些信息,但可能现有的引用中没有直接的单片机导图,所以需要根据常见的学习路径来构建。 用户提供的引用中,引用[1]提到不同硬件平台下的驱动开发,包括单片机,这可能涉及到单片机的基础知识。引用[2]强调了C语言和汇编的重要性,这在单片机学习中也很关键。引用[3]展示了嵌入式C语言的导图结构,可以作为参考。 接下来,我需要整理单片机学习的主要模块。通常包括基础知识、编程语言、开发工具、外设接口、项目实践等。每个模块下需要细分内容,比如基础知识包括体系结构、存储结构,编程语言涉及C和汇编,开发工具如Keil、Proteus等,外设如GPIO、UART、ADC等,还有实时操作系统和通信协议。 同时要确保符合用户的要求,使用中文回答,正确应用LaTeX格式,例如提到中断处理时使用$NVIC$。最后生成相关问题,可能涉及学习方法、关键点、资源推荐、项目实践等。需要检查引用是否相关,比如引用[2]提到学习C语言和汇编,引用[3]的结构可以参考,所以适当引用这些部分。</think>根据思维导图构建要求,结合嵌入式开发学习路径,整理单片机学习框架如下: ### 单片机学习思维导图(层级结构) **一、基础知识体系** 1. 单片机体系结构 - 哈佛vs冯诺依曼架构$^{[1]}$ - 核心部件:CPU、RAM、ROM、I/O端口 - 时钟树结构:内部/外部振荡器 2. 存储结构 - Flash存储器(程序存储) - SRAM(运行时数据) - EEPROM(参数存储) **二、编程语言基础** 1. C语言核心要素 - 内存管理:堆/栈/全局区(参考引用[2]) - 位操作:`&= ~(1<<n)`等位运算 - 指针应用:地址映射$0x40000000$ 2. 汇编语言基础 - 指令周期计算 - 中断服务程序编写 - 关键寄存器操作 **三、开发工具链** ``` 编译工具链 │ ├── Keil MDK ├── IAR EWARM └── GCC交叉编译 ``` **四、外设接口开发** - GPIO配置模式:推挽/开漏 - 中断系统:NVIC优先级管理$^{[3]}$ - 定时器应用:PWM生成$f=\frac{1}{(ARR+1)(PSC+1)T_{clk}}$ - 通信协议: - UART:波特率计算 - SPI:主从模式 - I2C:时序规范 **五、项目实践路径** 1. 基础实验:LED流水灯→按键扫描→LCD驱动 2. 综合项目:智能温控→CAN总线通信→低功耗设计 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值