C 语言工业级通用组件手写 11:环形 FIFO 缓冲区
目录前言一、环形 FIFO 核心本质与应用场景1. 什么是环形缓冲区2. 解决的核心痛点3. 典型工业级落地场景二、核心实现原理1. 双指针循环机制2. 零拷贝读写3. 字节流式存储三、工业级设计规范1. 封装性设计2. 接口设计原则3. 鲁棒性要求4. 线程安全约束四、完整可复用源码1. 头文件 ring_fifo.h2. 实现文件 ring_fifo.c五、实战演示环形缓冲区读写示例六、工业级进阶优化方向1. 线程安全加锁封装2. 单次一字节读写接口3. peek 窥探接口4. 批量分段读写七、高频面试考点与易错坑点1. 经典面试问答2. 常见易错坑点总结前言在嵌入式串口接收、网络报文缓冲、音频数据流、传感器高频采集、异步数据收发场景中普通数组缓存存在溢出、覆盖、数据丢失、读写冲突等致命问题。普通数组无脑缓存必须手动判空、判满、移动数据代码臃肿、极易出错、无法高频运行。环形 FIFO循环缓冲区是工业流式数据缓存的标准解决方案。 本篇手写一套极简、零拷贝、全覆盖、读写分离、防溢出、可线程安全的工业级环形缓冲区源码干净、无冗余、可直接投产适配所有流式数据收发场景。一、环形 FIFO 核心本质与应用场景1. 什么是环形缓冲区环形 FIFO 是首尾相连的循环队列。依靠读指针(r)、写指针(w)实现循环读写无需数据搬迁、零拷贝、性能极致。核心特性先进先出、循环复用内存、无数据挪动、无内存碎片、读写高效。2. 解决的核心痛点解决数组缓存溢出覆盖满状态自动拦截写入杜绝数据丢失。解决数据搬迁耗时普通队列出队需要整体前移FIFO 零搬迁。解决高频数据流卡顿O (1) 读写百万级吞吐无压力。解决收发速率不匹配缓存削峰适配突发数据、高频采样。解决代码冗余混乱统一标准接口全局通用缓存组件。3. 典型工业级落地场景串口 / 485/CAN 接收缓存中断高速接收、主线程慢速解析。网络数据流缓冲TCP 流式分包、UDP 报文缓存。音视频采集音频帧、视频帧连续流式缓存。传感器高频采集高速 AD、姿态、雷达数据缓存。异步解耦架构生产快、消费慢场景削峰缓冲。二、核心实现原理1. 双指针循环机制write_ptr数据写入位置read_ptr数据读取位置缓冲区满(write 1) % size read缓冲区空write read预留一个空位区分空 / 满状态是工业最简、零 BUG 标准方案。2. 零拷贝读写读写直接操作数组指针不拷贝、不移动、不遍历性能拉满。3. 字节流式存储按字节缓存适配任意协议、任意报文、任意长度数据通用性最强。三、工业级设计规范1. 封装性设计FIFO 结构体完全封装缓存地址、读写指针、缓冲区大小。外部不可篡改内部状态保证读写闭环安全。2. 接口设计原则接口函数功能说明fifo_init初始化环形缓冲区fifo_write写入指定长度数据fifo_read读取指定长度数据fifo_available获取剩余可写空间fifo_used获取当前已缓存数据长度fifo_clear清空缓冲区3. 鲁棒性要求空指针校验、长度合法性校验。写满自动拒绝、读空自动返回。无越界、无覆盖、无数据错乱。纯 C 零依赖、裸机 / RTOS/Linux 全平台适配。4. 线程安全约束单生产单消费天然线程安全嵌入式中断写、主线程读标配。多生产多消费需外层加锁适配高并发场景。四、完整可复用源码1. 头文件 ring_fifo.h#ifndef RING_FIFO_H #define RING_FIFO_H #include stdint.h #include stddef.h #ifdef __cplusplus extern C { #endif /* 环形FIFO句柄 */ typedef struct { uint8_t *buf; size_t buf_size; size_t w_ptr; size_t r_ptr; } ring_fifo_t; /** * brief 初始化环形缓冲区 * param fifo FIFO句柄 * param buf 缓存数组地址 * param buf_size 缓存数组大小 */ void fifo_init(ring_fifo_t *fifo, uint8_t *buf, size_t buf_size); /** * brief 写入数据到FIFO * param fifo FIFO句柄 * param data 待写入数据 * param len 写入长度 * return 实际写入字节数 */ size_t fifo_write(ring_fifo_t *fifo, const uint8_t *data, size_t len); /** * brief 从FIFO读取数据 * param fifo FIFO句柄 * param data 接收缓存 * param len 读取长度 * return 实际读取字节数 */ size_t fifo_read(ring_fifo_t *fifo, uint8_t *data, size_t len); /** * brief 获取缓冲区剩余可写空间 */ size_t fifo_available(ring_fifo_t *fifo); /** * brief 获取缓冲区已存储数据长度 */ size_t fifo_used(ring_fifo_t *fifo); /** * brief 清空缓冲区 */ void fifo_clear(ring_fifo_t *fifo); #ifdef __cplusplus } #endif #endif2. 实现文件 ring_fifo.c#include ring_fifo.h #include string.h void fifo_init(ring_fifo_t *fifo, uint8_t *buf, size_t buf_size) { if (fifo NULL || buf NULL || buf_size 0) { return; } fifo-buf buf; fifo-buf_size buf_size; fifo-w_ptr 0; fifo-r_ptr 0; } size_t fifo_write(ring_fifo_t *fifo, const uint8_t *data, size_t len) { if (fifo NULL || data NULL || len 0) { return 0; } size_t avail fifo_available(fifo); if (avail 0) { return 0; } // 限制最大写入长度 len len avail ? avail : len; size_t size1 fifo-buf_size - fifo-w_ptr; if (size1 len) { memcpy(fifo-buf[fifo-w_ptr], data, len); } else { memcpy(fifo-buf[fifo-w_ptr], data, size1); memcpy(fifo-buf, data size1, len - size1); } fifo-w_ptr (fifo-w_ptr len) % fifo-buf_size; return len; } size_t fifo_read(ring_fifo_t *fifo, uint8_t *data, size_t len) { if (fifo NULL || data NULL || len 0) { return 0; } size_t used fifo_used(fifo); if (used 0) { return 0; } len len used ? used : len; size_t size1 fifo-buf_size - fifo-r_ptr; if (size1 len) { memcpy(data, fifo-buf[fifo-r_ptr], len); } else { memcpy(data, fifo-buf[fifo-r_ptr], size1); memcpy(data size1, fifo-buf, len - size1); } fifo-r_ptr (fifo-r_ptr len) % fifo-buf_size; return len; } size_t fifo_available(ring_fifo_t *fifo) { if (fifo NULL) { return 0; } // 预留1字节区分空满 return (fifo-buf_size - 1 fifo-r_ptr - fifo-w_ptr) % fifo-buf_size; } size_t fifo_used(ring_fifo_t *fifo) { if (fifo NULL) { return 0; } return (fifo-w_ptr fifo-buf_size - fifo-r_ptr) % fifo-buf_size; } void fifo_clear(ring_fifo_t *fifo) { if (fifo NULL) { return; } fifo-w_ptr 0; fifo-r_ptr 0; }五、实战演示环形缓冲区读写示例#include stdio.h #include ring_fifo.h #define FIFO_BUF_LEN 32 uint8_t fifo_buf[FIFO_BUF_LEN]; int main(void) { ring_fifo_t fifo; fifo_init(fifo, fifo_buf, FIFO_BUF_LEN); uint8_t w_data[] INDUSTRIAL_FIFO_11; uint8_t r_data[32] {0}; // 写入数据 size_t w_len fifo_write(fifo, w_data, sizeof(w_data)); printf(成功写入 %zu 字节\n, w_len); printf(当前已缓存%zu 字节\n, fifo_used(fifo)); // 读取数据 size_t r_len fifo_read(fifo, r_data, sizeof(r_data)); printf(成功读取 %zu 字节\n, r_len); printf(读取内容%s\n, r_data); return 0; }运行效果循环读写正常、边界无越界、缓冲区满自动截断、空读取直接返回零丢失、零错乱、零崩溃。六、工业级进阶优化方向1. 线程安全加锁封装搭配互斥锁支持多线程并发读写。2. 单次一字节读写接口适配串口中断单字节写入场景。3. peek 窥探接口只读不弹出适配协议头解析、预判断报文。4. 批量分段读写适配超大数据流高速吞吐。七、高频面试考点与易错坑点1. 经典面试问答Q1环形 FIFO 为什么要预留一个空位答解决空满状态歧义。读写指针相等既可以是空也可以是满预留一位可以完美区分是工业最简无 BUG 方案。Q2环形缓冲区相比普通数组的优势答无需数据搬迁、无溢出覆盖、循环复用内存、性能稳定、适配异步收发。Q3单中断写主线程读是否需要加锁答不需要。单生产单消费模式指针互不抢占天然线程安全是串口驱动标准写法。Q4FIFO 核心设计思想答以空间换时间、循环复用内存、解耦生产消费速率、零拷贝高效流转。2. 常见易错坑点不预留空位空满判断错乱读写指针不取模数组越界读取不判空、写入不判满导致数据异常频繁数据 memmove 挪动性能极差边界包裹读写处理错误尾部数据丢失总结环形 FIFO 缓冲区是嵌入式流式数据处理的第一组件。所有串口、网络、音频、采集工程100% 依赖环形缓存。本篇实现工业标准、边界全覆盖、零 BUG、可直接投产补齐整套组件库数据流转核心能力。创作不易如果对你有帮助欢迎点赞、收藏、转发。

相关新闻

变频器的技术应用:接线与基本参数设置

变频器的技术应用:接线与基本参数设置

部分参考自《变频器与步进/伺服驱动技术完全精通教程》 化学工业出版社 图源:部分引自《台达 VFD-M变频器 使用手册》,其余引自互联网。 学习笔记,记录一下新变频器到手后,需要进行的配置工作。 说起来,变频器属于传动…

2026/7/21 15:49:46 阅读更多 →
GameVault错误处理与调试:常见问题排查与系统稳定性保障

GameVault错误处理与调试:常见问题排查与系统稳定性保障

GameVault错误处理与调试:常见问题排查与系统稳定性保障 【免费下载链接】gamevault-app Frontend for the self-hosted gaming platform for drm-free games 项目地址: https://gitcode.com/gh_mirrors/ga/gamevault-app GameVault是一款开源的自托管游戏平…

2026/7/21 15:49:46 阅读更多 →
从SVG到原生:NGraphics矢量图形格式转换全攻略

从SVG到原生:NGraphics矢量图形格式转换全攻略

从SVG到原生:NGraphics矢量图形格式转换全攻略 【免费下载链接】NGraphics NGraphics is a cross platform library for rendering vector graphics on .NET. It provides a unified API for both immediate and retained mode graphics using high quality native …

2026/7/21 15:49:46 阅读更多 →

最新新闻

UE5高分辨率渲染下阴影条纹问题的成因分析与系统解决方案

UE5高分辨率渲染下阴影条纹问题的成因分析与系统解决方案

1. 项目概述:高分辨率下的“条纹阴影”究竟是什么? 在UE5项目里,当你把渲染分辨率拉到4K、8K甚至更高,准备截一张惊艳的展示图或渲染一段高质量影片时,屏幕上那些本该平滑的阴影区域,却突然出现了令人抓狂的…

2026/7/21 20:52:21 阅读更多 →
Azure Local 2606 Release 解读:为什么一个“无新功能版本“仍值得关注(2602→2606 演进与升级价值·上篇)

Azure Local 2606 Release 解读:为什么一个“无新功能版本“仍值得关注(2602→2606 演进与升级价值·上篇)

未经同意,请勿转载! 适用版本:Azure Local 12.2602.1002.501(2602) → 12.2606.1003.205(2606) 文档来源:Whats new in Azure Local / Release information / Known issues / Azure …

2026/7/21 20:52:21 阅读更多 →
5分钟快速上手Taichi:Python高性能并行计算终极指南

5分钟快速上手Taichi:Python高性能并行计算终极指南

5分钟快速上手Taichi:Python高性能并行计算终极指南 【免费下载链接】taichi Productive, portable, and performant GPU programming in Python. 项目地址: https://gitcode.com/GitHub_Trending/ta/taichi Taichi(太极)是一个开源的…

2026/7/21 20:52:21 阅读更多 →
从鼠标依赖到键盘流:CVAT标注效率的快捷键深度优化指南

从鼠标依赖到键盘流:CVAT标注效率的快捷键深度优化指南

从鼠标依赖到键盘流:CVAT标注效率的快捷键深度优化指南 【免费下载链接】cvat Computer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise products,…

2026/7/21 20:52:21 阅读更多 →
FaceAISDK终极指南:3步打造Android离线人脸识别应用

FaceAISDK终极指南:3步打造Android离线人脸识别应用

FaceAISDK终极指南:3步打造Android离线人脸识别应用 【免费下载链接】FaceAISDK_Android Android on_device Face Recognition 、 Liveness detection and 1:N & M:N Face Search SDK 端侧可离线人脸识别 活体检测 以及1:N M:N 人脸搜索SDK 项目地址: https:…

2026/7/21 20:52:21 阅读更多 →
带标注的墙面红外缺陷数据集,可识别8种类型的缺陷,1874张图,支持yolo,coco json,voc xml,文末有模型训练代码

带标注的墙面红外缺陷数据集,可识别8种类型的缺陷,1874张图,支持yolo,coco json,voc xml,文末有模型训练代码

​ 带标注的墙面红外缺陷数据集,可识别8种类型的缺陷,识别率92.5%,1874张图,支持yolo,coco json,voc xml,文末有模型训练代码 模型训练指标参数: 模型训练图: 数据集拆分 总图数&a…

2026/7/21 20:51:21 阅读更多 →

日新闻

Octane Render与C4D汉化版安装与优化指南

Octane Render与C4D汉化版安装与优化指南

1. Octane Render与C4D的黄金组合:为什么选择这个方案?在三维创作领域,渲染器的选择往往决定了作品的最终呈现质量和工作效率。作为Cinema 4D(C4D)用户,Octane Render的GPU加速特性与实时预览功能&#xff…

2026/7/21 0:00:19 阅读更多 →
GPMC接口设计:异步/同步模式与多路复用配置实战

GPMC接口设计:异步/同步模式与多路复用配置实战

1. GPMC接口设计:从硬件连接到软件配置的全局视角在嵌入式系统开发中,尤其是基于TI Sitara系列如AM263x这类高性能微控制器的项目里,外部存储器的扩展几乎是绕不开的一环。无论是存放大量非易失性代码的NOR Flash,还是作为高速数据…

2026/7/21 0:00:19 阅读更多 →
UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

1. 项目概述:UE5 GAS RPG被动技能的核心价值在UE5里用GAS(Gameplay Ability System)做RPG游戏,主动技能像是你手里的武器,按一下打一下,逻辑直接,反馈也快。但被动技能,它更像是你身…

2026/7/21 0:00:19 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻