实际项目中的环形缓冲区
在实际项目中,环形缓冲区的设计要比之前讲到的原型稍微复杂一些,需要一些接口函数来实现数据结构封装。GitHub上有个大帅哥写了一个轻量的环形缓冲区库,可以学习参考,也可以直接集成到自己的项目中,功能已经非常完善。
特点
- 使用C语言编写(C11),与
size_t
兼容的大小数据类型 - 独立于平台,没有特定于体系结构的代码
- 先进先出(FIFO)缓冲区实现
- 无动态内存分配,数据为静态数组
- 使用优化的内存复制而不是循环来读取/写入内存中的数据
- 在作为单个写入和单个读取条目的管道时线程安全
- 在作为单个写入和单个读取条目的管道时中断安全
- 适用于在缓冲区和应用程序内存之间进行零拷贝的DMA传输
- 支持数据的查看、读取跳过和写入前进
- 实现事件通知的支持
- 用户友好的MIT许可证
要求
- C编译器
- 少于1kB的非易失性存储器
示例代码
用于读取和写入缓冲区的简化示例代码:
1 | /* 声明rb实例和原始数据 */ |
我们首先看下这个库的接口文件:
1 | /** |
首先,代码包含了一些必要的头文件,并检查是否在C++环境中。如果是,就使用extern "C"
来确保C++编译器以C语言的方式处理这个库。
然后,定义了一些类型和枚举。例如,lwrb_sz_t
和lwrb_sz_atomic_t
用于表示缓冲区的大小,lwrb_evt_type_t
是一个枚举,表示缓冲区操作的事件类型。
lwrb_t
是主要的数据结构,表示一个环形缓冲区。它包含了指向缓冲区数据的指针、缓冲区的大小、读写指针以及一个事件回调函数。与之前介绍的最简化的环形缓冲区相比,这个结构中还包含了一个缓冲区大小和一个事件回调函数。事件回调函数用于在缓冲区操作时通知应用程序。
接下来是一系列的函数声明,这些函数用于操作环形缓冲区。例如,lwrb_init
用于初始化一个环形缓冲区,lwrb_write
和lwrb_read
用于向缓冲区写入数据和从缓冲区读取数据。
最后,代码检查是否在C++环境中。如果是,就结束extern "C"
。
事件
在应用程序中使用 LwRB 时,获取有关不同事件的通知可能会很有用,例如在向缓冲区写入或读取数据时获得通知。
该库支持在缓冲区数据发生修改时调用的事件,这意味着在每次读取或写入操作时都会触发事件。
一些用例:
- 通知应用程序层 LwRB 操作已被执行并发送调试消息
- 当应用程序使用操作系统时,当已写入/读取足够数量的字节到/从缓冲区时,解锁信号量
- 在操作系统级别的消息队列中写入通知以唤醒另一个任务
注意: 每个修改 read
或 write
内部指针的操作都被视为读取或写入操作。唯一的例外是 重置 事件,它将两个内部指针都设置为 0
。
1 |
|
上述代码演示了如何设置 LwRB 缓冲区的事件回调函数以获取关于读取、写入和重置操作的通知。在每次读取或写入时,将调用相应的事件回调函数。