当前位置:网站首页>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;
}
边栏推荐
- [QNX Hypervisor 2.2 User Manual] 10.3 vdev gic
- 【指针内功修炼】深度剖析指针笔试题(三)
- C语言--环形缓存区
- (cf)Codeforces Round #811 (Div. 3)A--E详细题解
- [Study Notes Dish Dog Learning C] Dynamic Memory Management
- Multithreading JUC Learning Chapter 1 Steps to Create Multithreading
- Small Turtle Compilation Notes
- 异步编程解决方案 Generator生成器函数、iterator迭代器、async/await、Promise
- Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment
- Priority_queue element as a pointer, the overloaded operators
猜你喜欢
MySQL高级-读写分离-分库分表
Pine Script | How to display and typeset a plot switch?
Web APIs BOM- 操作浏览器:swiper 插件
【指针内功修炼】深度剖析指针笔试题(三)
SAP SD模块前台操作
Rongyun "Audio and Video Architecture Practice" technical session [complete PPT included]
There are n steps in total, and you can go up to 1 or 2 steps each time. How many ways are there?
SAP SD module foreground operation
系统太多,多账号互通如何实现?
实例038:矩阵对角线之和
随机推荐
APP电商如何快速分润分账?
pytorch applied to MNIST handwritten font recognition
2022广东省安全员A证第三批(主要负责人)考试题库及模拟考试
LeetCode:899. 有序队列【思维题】
What is SVN (Subversion)?
What is the source of flinkcdc consuming mysql binlog data without sqltype=delete
Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment
esp32 releases robot battery voltage to ros2 (micro-ros+CoCube)
Qt中对象树的机制介绍以及底层实现,各种结果分析:(以及自己写容易犯错的点)
Promise solves blocking synchronization and turns asynchronous into synchronous
贪吃蛇游戏Bug解析及功能扩展
QNX Hypervisor 2.2 user manual] 10.1 gm vdev options
Variable string
ssh服务详解
Ant - the design of the Select component using a custom icon (suffixIcon attribute) suffixes, click on the custom ICONS have no reaction, will not display the drop-down menu
Zabbix set up email alert + enterprise WeChat alert
QNX Hypervisor 2.2用户手册]10.1 通用vdev选项
STM8S项目创建(STVD创建)---使用 COSMIC 创建 C 语言项目
参加Oracle OCP和MySQL OCP考试的学员怎样在VUE预约考试
系统太多,多账号互通如何实现?