说明

  • RingBuffer(环形缓冲区)也叫做圆形队列(circular queue),使用场景比较广泛,例如:Linux内核中网络数据包的缓存,系统日志的存储等多处使用,以及被广泛的应用于异步通信以及嵌入式设备中,提供高效的数据缓存读写操作。

特征

  1. 环形缓冲区体现了Ringbuffer是缓冲区设计的一种。
  2. 圆形队列(circular queue)体现了其数据操作满足FIFO(先进先出)原则。

优点

  1. 内存循环使用,固定大小的内存区域,不需要申请和释放内存,内存重复使用。

缺点

  1. 需要进行两次内存拷贝,第一次从外部拷贝到Ringbuffer,第二次从Ringbuffer拷贝到外部使用,对于大块数据,性能影响明显。

原理

  • 环形缓冲区通常有一个读指针和一个写指针,发生读写操作时,读写指针跟随操作进行移动,读指针指向下一次读取数据的内存地址,写指针指向下一次写数据的内存地址。
  • 当读写指针发生越界时,需要将读写指针重置,以便内存成环,常见有以下两种做法:
  1. 单字节,读写指针根据buffer size 取模。
  2. 多字节,读写指针根据buffer size 判断,超过size置为0。
  • 注意:环是逻辑上的描述,在实际内存空间中是线性的。

关键问题

  • 当读写指针移动时,可能出现三种情况:
  1. 实际线性内存空间中,读指针在前,写指针在后。
  2. 实际线性内存空间中,读写指针指向同一个位置。
  3. 实际线性内存空间中,写指针在前,读指针在后。
  • 第二种情况,当读写指针指向同一位置时,此时空间是满还是空?实际情况下空和满都有可能,Ringbuffer还未使用或者读操作追上写操作时,读写指针指向同一位置,此时为空,Ringbuffer写操作追上读操作时,此时为满。

解决办法

  1. 保持一个存储单元为空
  • 写数据时,Ringbuffer空闲空间等于实际空闲空间减一,以保持至少一个存储单元为空,这样就避免了出现读指针被写指针追上的情况(即:缓冲区满的情况);读数据不做限制。
  • 这种处理方法,如果读写指针指向同一位置,则缓冲区为空;如果写指针位于读指针的相邻后一个位置,则缓冲区为满。
  1. 使用变量计数
  • 定义一个变量来保存数据长度,写操作时,变量加上已写数据长度,读操作时,变量减去已读数据长度,通过该变量即可获知空闲空间。
  1. 镜像逻辑地址法
  • 在国产物联网操作系统RT-thread中使用了一种非常特殊的方式来表示队满还是空。

镜像逻辑地址法

  • 这篇Blog可以借鉴,但是原理层面感觉没讲清楚。
  • 解释:
  1. 镜像:在逻辑层面将初始位置的读写指针认为是处于镜像的正面,当指针发生翻转(重置为0)时认为指针进入镜像的反面,再翻转回来认为处于镜像的正面,类似于这样循环。
  2. 当读写指针处于同一镜像时,说明读写指针翻转次数是一样的(buffer size牵扯读写指针导致的),只会出现写指针在读指针前面和读写指针位置一样的情况,读写指针位置一致则说明:空间为空。
  3. 当读写指针处于不同镜像时,说明读写指针翻转次数相差一次,只会出现读指针在写指针前面和读写指针位置一样的情况,读写指针位置一致则说明:空间为满。
  • RT-Thread中定义的 rt_ringbuffer 结构体,如下:
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;
};

RingBuffer相关推荐

  1. .net thread操作串口_听说你不知道 RT-Thread 有个 ringbuffer

    在嵌入式开发中,我们经常需要用到 FIFO 数据结构来存储数据,比如任务间的通信.串口数据收发等场合.很多小伙伴不知道 RT-Thread 为我们提供了一个 ringbuffer 数据结构,代码位于: ...

  2. 线程安全的无锁RingBuffer的实现

    这里的线程安全,是指一个读线程和一个写线程,读写两个线程是安全的,而不是说多个读线程和多个写线程是安全的.. 在程序设计中,我们有时会遇到这样的情况,一个线程将数据写到一个buffer中,另外一个线程 ...

  3. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue, RingBuffer

    1. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue ArrayBlockingQueue, LinkedBlocking ...

  4. disruptor RingBuffer初始化与生产者事件产生

    在Disruptor中,为了防止伪共享导致的性能降低,所有元素都会在前后尽量填充64个字节以保证在cpu以64字节缓存数据的时候,在缓存行中,都只会有自己所需要的数据,不会导致缓冲行的更新影响到别的c ...

  5. disruptor 框架使用以及ringbuffer原理解析

    Disruptor 概述 子主题 1 从功能上来看,Disruptor 是实现了"队列"的功能,而且是一个有界队列.那么它的应用场景自然就是"生产者-消费者"模 ...

  6. Disruptor RingBuffer 原理

    Disruptor 源码 https://github.com/LMAX-Exchange/disruptor/blob/master/README.md https://github.com/LMA ...

  7. 聊聊ringbuffer

    文章目录 计数法实现 镜像指示位实现 ringbuffer,是环形缓存区, 或叫环形队列. 不同于一般常见的队列,环形队列首尾相连,通过移动指针来控制队列中内容的读写. 这样做有什么好处呢? 最大的好 ...

  8. 二维数组8:设计题 RingBuffer的原理和实现

    ​RingBuffer是笔者在微博遇到的一个面试题. RingBuffer的特征不需要记住,面试官会告诉你的,并且告诉你一些要求,然后根据这些要求来设计就行了. RingBuffer这种结构的使用场景 ...

  9. Disruptor源码解析三 RingBuffer解析

    目录 系列索引 前言 主要内容 RingBuffer的要点 源码解析 系列索引 Disruptor源码解析一 Disruptor高性能之道 Disruptor源码解析二 Sequence相关类解析 D ...

  10. 知识巩固源码落实之3:缓冲区ringbuffer

    1:背景介绍: 在日常业务开发中,使用缓冲区进行临时存储的业务场景也比较多,如tcp每个连接底层都维持一个发送缓冲区和接收缓冲区. 实现一个ringbuffer,做代码备用.(可以考虑如何对ringb ...

最新文章

  1. java缓冲流 复制文件_java使用缓冲流复制文件的方法
  2. 电气simulink常用模块_16种常用模块电路分析,电气工程师的必备
  3. android xml文件操作类,android操作xml
  4. html2image api,图像标签_图像识别 Image_API参考_API_华为云
  5. c 语言中unsigned char类型变量占用内存大小,C数据类型
  6. 计算机一级办公软件试题,计算机一级《MS Office》练习题(含答案)
  7. findbugs-dea_FindBugs和JSR-305
  8. phpcmsV9上传文件类型的设置
  9. Spark SQL 1.3.0 DataFrame介绍、使用及提供了些完整的数据写入
  10. rabbitmq的通配符模式(Topic Exchange)的*和#区别
  11. 全局bigdecimal反序列化转String返回数据
  12. MDUI登陆注册案例
  13. 使用JS和CSS实现图片的3D透视效果及动画
  14. 读取采购订单附件(GOS)-[BDS_GOS_CONNECTIONS_GET/SO_DOCUMENT_READ_API1]
  15. [AHK]调用小米笔记本电脑的音量调节功能
  16. Python学习之路:函数传递可变参数与不可变参数
  17. 计算机桌面成英文怎样变成中文版,怎样把电脑语言设置成英文
  18. CAD设置图层透明显示
  19. 微机原理与接口技术的基础知识
  20. 新变种Emotet恶意样本分析

热门文章

  1. php自动关机代码,win7定时关机命令是什么
  2. 2D图像像素点操作——平移,旋转,缩放 tcy
  3. 听完周杰伦的《Mojito》,我不禁想用分子料理做几颗
  4. python-库汇总
  5. 简述XSS攻击及其防范措施
  6. 【PS】如何简单的处理带晒伤皮肤的婚纱照?红斑/脱皮/减淡红色
  7. matlab仿真超声波测距,超声波测距仪制作-Arduino中文社区 - Powered by Discuz!
  8. MySQL 插入时,出现‘“Incorrect string value: ‘\\xF0\\x9F\\x98\\x85...‘ for column ‘commens‘ at row 3‘
  9. mongoDB快速入门
  10. 9款非常适合Sketchup的渲染插件以及优点介绍