推荐星级:
  • 1
  • 2
  • 3
  • 4
  • 5

环形缓冲区设计误区澄清

资料介绍

环形缓冲区设计答疑与误区澄清 【缘起】 环形缓冲区(ring buffer)是嵌入式里最常用的数据结构之一,用于在生产者(如中断、DMA)和消费者(如主循环、任务)之间传递数据。看起来简单,但设计起来坑不少。我最初设计时以为只要有个数组和两个指针就行,结果在边界、并发和溢出上栽了好几个跟头,这篇把这些经验梳理出来。 事情起因是一个串口接收模块。数据从中断里进,主循环里取,要求不能丢数据、不能错乱。最初用简单的线性缓冲区,满了就清空,结果高频数据一来就丢。换环形缓冲区后,才真正解决了"写入不阻塞、读取不掉队"的问题。 这篇按工程手记的顺序,把从第一轮尝试到最终方案的完整过程写清楚,每个环节都对应一个值得注意的设计要点。 【第一轮尝试】 第一轮尝试,是最朴素的环形缓冲区:一个固定大小数组,加两个下标 head 和 tail。写入时写 tail 位置并前移,读取时读 head 位置并前移。逻辑上很直观,代码也简单,几分钟就能写出来。 但很快就暴露了问题。首先是"空"和"满"两种状态无法区分,因为 head == tail 既可能表示空,也可能表示满。为了区分,往往需要浪费一个存储单元,或者在结构体里加一个 count 计数。我最初用 count,倒也没出错。 更大的隐患是并发的读写。中断里写入、主循环里读,两个下标如果没做好原子保护,就可能出现"读到一半被覆盖"或"指针错位"的情况。第一轮尝试只实现了基本逻辑,完全没有考虑并发安全,这是后续要重点解决的问题。 【遇到的坑】 第一个坑,是边界索引的取模运算。当 head 或 tail 达到数组末尾时,需要回绕到 0。如果直接用 % 运算,对非 2 的幂次数组会引入除法开销,实时性受影响。而用 2 的幂次大小配合位运算,则高效得多,但要求数组大小是 2 的幂。 第二个坑,是并发读写时的竞态。

部分文件列表

文件名 大小
环形缓冲区设计误区澄清.docx 39K

全部评论(0)

暂无评论

上传资源 上传优质资源有赏金

  • 打赏
  • 30日榜单

推荐下载