首页 > 其他分享 >ring buffer

ring buffer

时间:2022-09-07 11:25:01浏览次数:68  
标签:rt buffer 环形 索引 缓冲区 ring

概述

ring buffer称作环形缓冲区,也称作环形队列(circular queue),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。

使用场景

在任务间的通信、串口数据收发、log缓存、网卡处理网络数据包、音频/视频流处理中均有环形缓冲区(ring buffer) 的应用。在RT-Thread的ringbuffer.c和ringbuffer.h文件中,Linux内核文件kfifo.h和kfifo.c中也有环形缓冲区(ring buffer)的代码实现。

特点

  • 适合于事先明确了缓冲区的最大容量的情形。缓冲区的容量(长度)一般固定,可以用一个静态数组来充当缓冲区,无需重复申请内存;
  • 如果缓冲区的大小需要经常调整,就不适合用环形缓冲区,因为在扩展缓冲区大小时,需要搬移其中的数据,这种场合使用链表更加合适;

实现

一般的,对一个环形缓冲区进行读写操作,最少需要4个信息:

  • 在内存中的实际开始位置(例如:一片内存的头指针,数组的第一个元素指针);
  • 在内存中的实际结束位置(也可以是缓冲区实际空间大小,结合开始位置,可以算出结束位置);
  • 在缓冲区中进行写操作时的写索引值;
  • 在缓冲区中进行读操作时的读索引值。

缓冲区开始位置和缓冲区结束位置(或空间大小) 实际上定义了环形缓冲区的实际逻辑空间和大小。读索引和写索引标记了缓冲区进行读操作和写操作时的具体位置。

struct rt_ringbuffer
{
    rt_uint8_t *buffer_ptr;
    rt_uint16_t read_mirror : 1;
    rt_uint16_t read_index : 15;
    rt_uint16_t write_mirror : 1;
    rt_uint16_t write_index : 15;
    rt_int16_t buffer_size;
};
struct kfifo {
	unsigned char *buffer;	/* the buffer holding the data */
	unsigned int size;	/* the size of the allocated buffer */
	unsigned int in;	/* data is added at offset (in % size) */
	unsigned int out;	/* data is extracted from off. (out % size) */
	spinlock_t *lock;	/* protects concurrent modifications */
};

总结

  • 环形缓冲区(ring buffer)适合于事先明确了缓冲区的最大容量的情形。缓冲区的容量(长度)一般固定,可以用一个静态数组来充当缓冲区,无需重复申请内存;
  • 如果缓冲区的大小需要经常调整,就不适合用环形缓存区,因为在扩展缓冲区大小时,需要搬移其中的数据,这种场合使用链表更加合适;
  • 因为缓冲区成头尾相连的环形,写操作可能会覆盖未及时读取的数据,有的场景允许这种情况发生,有的场景又严格限制这种情况发生。选择何种策略和具体应用场景相关;
  • 环形缓冲区(ring buffer)特别适合于通信双方循环发送数据的场景;
  • 镜像指示位是一种高效判断缓冲区是否为空或满的策略,在RT-Thread和linux中都使用了该策略(或者是该策略的扩展),其能够保证在只有一个读线程(或进程)和一个写线程(或进程)中无需锁也能做到线程安全;
  • 注意区分写指针和写索引,读指针和读索引,最终对缓冲区进行操作还是需要写索引和读索引;
  • 如果自己嵌入式项目中需要使用环形缓冲区(ring buffer),可以借鉴linux 2.6版本的kfifo实现,很容易改写,而且非常高效。

标签:rt,buffer,环形,索引,缓冲区,ring
From: https://www.cnblogs.com/lygin/p/16664708.html

相关文章

  • 15445第一阶段笔记+Buffer Pool(2019)
    15445第一阶段笔记+BufferPool(2019)概念page与frame​ 块,页,是对同一概念的不同叫法,取决于场景不同。其表述的都是磁盘上某一柱面上的连续扇区(固定数目)。数据在磁盘和缓......
  • Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring BeanUtils,Cglib
    引用于:https://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html     比较的是四种复制的方式,分别为Apache的BeanUtils和PropertyUtils,Spring的BeanUtils......
  • Spring 中毒太深!离开 Spring 我居然连最基本的接口都不会写了。。。
    来源:cnblogs.com/lonely-wolf/p/14127957.html随着Spring的崛起以及其功能的完善,现在可能绝大部分项目的开发都是使用Spring(全家桶)来进行开发,Spring也确实和其名字一......
  • cypress安装时npm报错:npm WARN deprecated querystring@0.2.0: The querystring API
    处理方法一:更新npm版本:npminstall-gnpm使用淘宝镜像重新安装依赖:npminstall--registry=https://registry.npm.taobao.orgnpminstall-gcnpm--registry=https......
  • Springboot定义全局异常类详解
    前言当我们在开发过程中,会因为一些异常程序出现500,如果直接显示给客户看,这样很不友好。并且对我们后期维护,排查bug很困难。准备1.创建一个SpringBoot项目,引入web依赖,......
  • [Google] LeetCode 1554 Strings Differ by One Character 哈希
    Givenalistofstringsdictwhereallthestringsareofthesamelength.Returntrueifthereare2stringsthatonlydifferby1characterinthesameindex......
  • Spring之旅01
    一、Spring概述1.1web项目开发中的耦合度问题在Servlet中需要调用service中的方法,则需要在Servlet类中通过new关键字创建Service的实例1.2面向接口编程面向接......
  • springboot官方文档解读
    官网地址:https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/1第一个springboot项目我们在一个路径下面创建pom.xml文件<?xmlversion="1.0"encod......
  • 关于buffer
    创建Buffer实例alloc:创建指定字节大小的bufferallocUnsafe:创建指定大小的buffer(不安全)from:接收数据,创建bufferBuffer实例方法fill:使用数据填充bufferwrite:向bu......
  • 1.Spring jar包依赖
    commons-clicommons-cli1.4commons-codeccommons-codec1.9commons-loggingcommons-logging1.2org.apache.httpcomponentsfluent-hc4.5.5apache-httpc......