当前位置:网站首页>C language -- ring buffer
C language -- ring buffer
2022-08-04 02:35:00 【Coder_Pixiu】
How the ring buffer works
Ring buffers are fixed-size buffers,Works like memory is contiguous and loopable.在生成和使用内存时,There is no need to clear all the original data,只要调整head/tail指针即可.当添加数据时,head指针前进.当使用数据时,tail指针向前移动.当到达缓冲区的尾部时,指针又回到缓冲区的起始位置.

优势:When there is a lot of data but you don't need to store it all,Computers process data first,After processing, the data will be released,Proceed to the next one.Then the memory for the processed data will be wasted.因为后来的数据只能往后排队,If the remaining data are moved forward once,Efficiency will be greatly reduced.Hence the circular queue.The core is to apply for a piece of memory,Connect them end to end by a special method,形成一个闭环的内存地址.这样既可以继续处理源源不断的数据,There is no need to apply for new memory space to temporarily store new data,效率大大提高.
劣势:One of the most important features of the ring buffer is the matching between the speed of writing and the speed of reading,环形缓冲区一般是将数据先写入缓冲区内,然后有个写的指针位置,但是不能超过读的位置,Because the data has not been read yet,write data,This will cause the data to be overwritten by new data before it has been read,造成数据的丢失.Reading data is the same principle,The read pointer cannot exceed the write location,这样就会读到之前读过的数据,造成数据的重复.空间如果设置的太大,会造成内存的浪费,有内存一直处于空闲状态,If the space is set too small,可能会造成读的速度快于写的速度,导致读的过程中会有短暂的等待时间,造成效率不是最高.
1、写入数据<缓冲区

2、写入数据>缓冲区

代码:
#include "RingBuffer.h"
static UINT16 validlen; //已使用的数据长度
static UINT8* pHead = NULL; //The first address of the ring buffer
static UINT8* pTail = NULL; //Ring buffer end address
static UINT8* pValid = NULL; //The first address of the used buffer
static UINT8* pValidTail = NULL; //The end address of the used buffer
//malloc申请空间
void initRingbuffer(void)
{
if(pHead == NULL)
{
pHead = (char*) malloc(BUFFER_SIZE);
}
pValid = pValidTail = pHead;
pTail = pHead + BUFFER_SIZE;
validlen = 0;
}
//Free the ring buffer
void releaseRingbuffer(void)
{
if(pHead != NULL)
free(pHead);
pHead = NULL;
}
/*************************************************************/
/******功能:Initializes the specified ring buffer *****/
/******param:@buffer:Defines the first address of the static buffer array
param:@size:The size of this buffer ******/
/************************************************************/
void InitRingBuffer(UINT8* buffer, UINT16 size)
{
if(pHead == NULL)
{
pHead = buffer;
}
pValid = pValidTail = pHead;
pTail = pHead + size;
validlen = 0;
}
/***********************************************************/
/******功能:向缓冲区写入数据 *****/
/******param:@buffer 写入的数据指针
@len 写入的数据长度 ******/
/******return:-1 The length of the data written is too large -2:The buffer is not initialized *****/
/***********************************************************/
int writeRingbuffer(UINT8* buffer, UINT32 len)
{
UINT16 len1, len2, movelen;
if(len > BUFFER_SIZE)
{
return -1;
}
if(pHead == NULL)
{
return -2;
}
assert(buffer);
//将要写入的数据copy到pVaildTaill处
if(pValidTail+len > pTail)
{
len1 = pTail - pValidTail; //放到尾部
len2 = len - len1; //The position where the rear can't be put down,从头开始放
memcpy(pValidTail, buffer, len1);
memcpy(pHead, buffer + len1, len2);
pValidTail = pHead + len2; //New valid data
}else
{
memcpy(pValidTail, buffer, len);
pValidTail += len; //End of new valid data area
}
//Recalculate the starting position of the used area
if(validlen + len > BUFFER_SIZE)
{
movelen = validlen + len - BUFFER_SIZE;
if(pValid + movelen > pTail) //需要分成两段
{
len1 = pTail - pValid;
len2 = movelen - len1;
pValid = pHead + len2;
}else
{
pValid += movelen;
}
validlen = BUFFER_SIZE;
}else
{
validlen += len;
}
return 0;
}
/*************************************************************/
/******功能:Reads the specified length of data from the buffer *****/
/******param:@buffer Pointer to receive read data
@length 读取的数据长度 ******/
/******return:-1 The buffer is not initialized >0:Valid data size read *****/
/*************************************************************/
int readRingbuffer(UINT8* buffer, UINT32 len)
{
UINT16 len1, len2;
if(pHead == NULL)
{
return -1;
}
assert(buffer);
if(len > validlen)
{
len = validlen;
}
if(validlen == 0)
{
return 0;
}
if(pValid + len > pTail) //需要分成两段copy
{
len1 = pTail - pValid;
len2 = len - len1;
memcpy(buffer, pValid, len1); //第一段
memcpy(buffer + len1, pHead, len2); //第二段 ,Wrap around to the beginning of the entire store
pValid = pHead + len2; //Update the start of the used buffer
}else
{
memcpy(buffer, pValid, len);
pValid += len; //Update the start of the used buffer
}
validlen -= len; //Update the length of the used buffer
return len;
}
/*************************************************************/
/******功能:Get the used buffer data length *****/
/******param:void ******/
/******return:The data length of the used buffer *****/
/************************************************************/
UINT32 getRingbufferValidLen(void)
{
return validlen;
}
边栏推荐
- 验证码业务逻辑漏洞
- 各位大佬好,麻烦问一下flink cdc oracle写入doris的时候,发现cpu异常,一下下跑
- 云开发旅游打卡广场微信小程序源码(含视频教程)
- Continuing to pour money into commodities research and development, the ding-dong buy vegetables in win into the supply chain
- 【学习笔记之菜Dog学C】动态内存管理
- Engineering drawing review questions (with answers)
- 简单排序(暑假每日一题 14)
- STM8S105K4T6------串口发送和接收
- sudo 权限控制,简易
- 什么是SVN(Subversion)?
猜你喜欢
随机推荐
(cf)Codeforces Round #811 (Div. 3)A--E详细题解
自制蓝牙手机app控制stm8/stm32/C51板载LED
0.1 前言
Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment
实例039:有序列表插入元素
验证码业务逻辑漏洞
多线程间的通信方式你知道几种?
What is the source of flinkcdc consuming mysql binlog data without sqltype=delete
uni-app 从零开始-基础模版(一)
C语言力扣第54题之螺旋矩阵。模拟旋转
APP电商如何快速分润分账?
架构实战营模块三作业
Example 035: Setting the output color
【原创】启动Win10自带的XPS/OXPS阅读器
织梦内核电动伸缩门卷闸门门业公司网站模板 带手机版【站长亲测】
v-model
Web APIs BOM- 操作浏览器:swiper 插件
FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
Homemade bluetooth mobile app to control stm8/stm32/C51 onboard LED
In a more general sense, calculating the displacement distance and assumptions








