LFBB(Lock Free Bipartite Buffer)就是一个用 C11 写的“更聪明的环形缓冲区”。它在单生产者-单消费者场景下无锁,高性能,特意为需要连续内存区(给 DMA、直接处理、避免拷贝)的场景设计。简单、轻量、无动态分配,工程里用来当数据通道再合适不过了。
LFBB 是什么(通俗说法)
传统环形缓冲区有个尴尬:写/读可能跨越缓冲尾部,导致不能一次拿到连续内存。LFBB 把缓冲区“分段”管理,能保证当有足够空间/数据时,总能返回一段连续内存给你去 DMA 或直接处理。它还维护一个“invalidate(失效)索引”来跳过那些被跳过的空洞——这样既安全又高效。
它解决了哪些痛点
-
• 想把数据交给 DMA,必须要连续内存?LFBB 可以直接给你连续块,省去中间拷贝。
-
• 想在缓冲里直接处理数据(不出队)?LFBB 支持。
-
• 读写可能失败或只处理部分数据?LFBB 的接口能告诉你用了多少,再回收或放弃。
-
• 单生产者单消费者场景里想要无锁且高吞吐?LFBB 做到了。
-
快速信息表
|
项目 |
描述 |
|
语言 |
C11(标准) |
|
适用场景 |
嵌入式(含 DMA)、实时流、高性能应用 |
|
线程模型 |
单生产者-单消费者 无锁(lock-free) |
|
动态分配 |
无(用户提供缓冲区) |
|
许可证 |
MIT |
|
获取方式 |
CMake FetchContent / git submodule / release 下载 |
如何安装与集成(实操步骤)
-
• 获取库:推荐用 CMake 的 FetchContent,或者把 repo 当 submodule 拉进来,简单直接。
-
• 编译:把库加到你的 build 中(或者直接把源码放进工程),不需要复杂依赖。
-
• 配置宏:有两个重要宏 LFBB_MULTICORE_HOSTED 和 LFBB_CACHELINE_LENGTH,根据目标平台决定是否开启缓存行对齐。
示例(伪代码)——消费者:
size_t data_available;
uint8_t *read_ptr = LFBB_ReadAcquire(&lfbb, &data_available);
if (read_ptr) {
size_t used = DoWork(read_ptr, data_available);
LFBB_ReadRelease(&lfbb, used);
}
生产者(与 DMA 搭配):
uint8_t *w = LFBB_WriteAcquire(&lfbb, size);
if (w) {
StartDma(w, size);
// DMA 完成后:
LFBB_WriteRelease(&lfbb, size);
}
关于缓存与嵌入式的注意事项
嵌入式系统用 DMA 或多核且有缓存时,必须自己做 cache sync:要么用平台提供的 DSB、缓存失效指令,要么把该内存页设置成不缓存(MMU/MPU)。LFBB 默认不给你自动同步(太依赖平台),所以别忘了这步,不然数据会怪怪的。
另外,LFBB 不会自动对齐你的写/读边界,写入时要保证按你需要的对齐方式来做。
优缺点
优点:
-
• 无锁、高性能;适合 DMA 场景;没有动态内存;接口简单易用。
缺点/限制: -
• 只在单生产者-单消费者场景保证无锁性质,复杂线程模型需谨慎;
-
• 缓存同步由用户负责(嵌入式需额外工作);
-
• 不做自动对齐,使用时要留心数据边界;
-
• 如果你的场景需要多生产者或多消费者,需外部同步或改设计。
总结
LFBB 很“直接、好用”,专为那些需要连续内存、低延迟、高吞吐的场景设计,在单生产者-单消费者里表现非常棒。要是你在做嵌入式 DMA、音视频流、或者任何要减少拷贝的高频数据通道,强烈值得试试。别忘了缓存同步和对齐这些工程细节。
项目地址:https://github.com/DNedic/lfbb