[common c/c++] ring buffer/circular buffer 环形队列/环形缓冲区

前言:

ring buffer / circular buffer 又名环形队列 / 环形缓冲区,其通过开辟固定尺寸的内存来实现反复复用同一块内存的目的。由于预先开辟了固定尺寸的内容,所以当数据满的时候,可以有两种处理方式,具体使用哪一种按照实际需求,具体如下:

1)当队列满的时候,新来的数据会覆盖最古老的数据,这种数据结构的特点是数据的写入不会因为队列满了而停止,同时也会导致旧数据的丢失,常用在一些对老旧数据不敏感的场景。如果数据很重要且不希望被丢弃,那么不要使用这种覆盖的模式,比如 流媒体场景下,每一帧数据都要确保完整地被渲染出来,不然会出现跳帧和音画同步无法完成等问题,所以不适合这种模式。

2)当数据满的时候,block 或者禁止写入操作,直到队列有空间时再允许写入。这种模式下可以保证数据不被覆盖掉。

环形队列优势在于,不需要反复开辟(alloc)内存空间,可以反复复用同一块内存区域,这样避免了反复申请释放内存带来的时间开销和内存碎片化。

ps:下文以环形队列来代替 ring buffer / circular buffer / 环形缓冲区。

环形队列的最小可操作单位并不是固定的,可以是一个字节的内存空间,也可以是N个字节,或者是其他数据结构体类型的内存尺寸,这取决于环形队列最小单元的尺寸。比如  char ringbuffer[409600] 的环形队列,可操作的最小单位一般就是一个字节,long long ringbuffer[409600] 的环形队列,很可能就是按照8个字节作为一个最小粒度单元的。

下文中使用单位一次来指代环形队列的最小可操作元素,同样地一个步进单位也是指一次地址移动的步长。

设计思路:

环形队列 的管理需要 4 个 index 值 ,队列开始处 start,队列结束处 end,已填充区域的头部 head,已填充区域的尾部 tail。因为环形队列是固定尺寸的缓冲区,所以一般情况下使用内存地址来表示者 4个 index。

start 和 end 表示开辟的固定内存空间的 起始位置,用来限定整个环形队列可以游走的空间范围。start指向内存开始的地址,end指向内存结束的地址。

head 和 tail 反映已经写入数据的内存空间的 起始位置,这里用反映而不是用表示是说明 head 和 tail 对于地址的表示 和 start 和 end 有所不同。 head 指向下一次可写入地址的开始位置,注意这里是下一次可写入,而不是上一次写入的尾部。tail 指向已经写入区域的最老的内存单元的地址。head 指向的是未被写入的地址,tail指向的是已经被写入的地址。

几个重要的限定条件:

1)head index 只能指向未被写入的位置。

A ‘head’ index - the point at which the producer inserts items into the buffer.

2)tail index 可以指向任何位置。

A ‘tail’ index - the point at which the consumer finds the next item in the buffer.

3)队列满:当 head index 前进一个 单位后等于 tail index 的时候,队列就满了,这个时候其实还剩余一个未被写入的单位,因为 head 永远是指向未被写入的单位。所以队列满等于 head + sizeof(element) = tail 。如果head 和 tail 是指针,那么 head + 1 = tail,因为指针 加 1 会根据指针类型自动调节字节步长。

the buffer is full when the head pointer is one less than the tail pointer.

伪代码:

bool isempty(){

  if(tail == head)

    return true;

  else

    return false;

}

4)队列空:当 tail index 等于 head index 的时候,队列就空了。

Typically when the tail pointer is equal to the head pointer, the buffer is empty

伪代码:

bool isfull(){

  if(tail == head+1)

    return true;

  else

    return false;

}

上面伪代码只做说明,不可实用,因为实际情况下需要考虑到 head 和 tail 到达和越过  end 时需要重置到 start 位置重新计算的问题。

是否需要考虑同步问题:

是,需要考虑同步问题。

单生产者和单消费者场景下,产消双方没有机会操作相同的队列单元,但是head index 和 tail index 还是存在 race condition 的。

多生产者和多消费者场景下,更需要加锁。

implement with c++ 11:

队列满则覆盖版老数据版本:

队列满则等待可用空间版本:

implement with c:

队列满则覆盖版老数据版本:

队列满则等待可用空间版本:

lock free practice:

队列满则覆盖版老数据版本:

队列满则等待可用空间版本:

参考:

Circular Buffers — The Linux Kernel documentationicon-default.png?t=N7T8https://www.kernel.org/doc/html/v4.20/core-api/circular-buffers.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/158328.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用移动互联、物联网、智能算法、地理信息系统、大数据分析等信息技术开发的智慧工地云平台源码

智慧工地是指利用移动互联、物联网、智能算法、地理信息系统、大数据挖掘分析等信息技术,提高项目现场的“人•机•料•法•环•安”等施工要素信息化管理水平,实现工程施工可视化智能管理,并逐步实现绿色生态建造。 技术架构:微…

【SOC基础】单片机学习案例汇总 Part2:蜂鸣器、数码管显示

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

【Proteus仿真】【Arduino单片机】RGB彩灯

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使用WS2812 RGB彩灯等。 主要功能: 系统运行后,RGB彩灯花样显示。 二、软件设计 /* 作者:嗨小易(…

APUS成为深圳市人工智能行业协会理事单位,CEO李涛受聘专家

近日,APUS正式成为深圳市人工智能行业协会理事单位,APUS董事长兼CEO李涛同时受聘为协会专家委员会专家。 深圳市人工智能行业协会成立于2017年,由电子通信、大数据、计算机视觉、自然语言处理等AI相关领域企事业单位组成,致力于加…

使用IDEA生成JavaDoc文档(IDEA2023)

1、Tool-->Generate JavaDoc 2、配置生成JavaDoc文档 1、选择生成范围,可以根据需要选择单独一个文件或者包,也可以是整个项目 2、输出目录,要把JavaDoc文档生成在哪个文件中,最好新建一个文件夹结束 3、Local:…

OpenGL_Learn04

我这边并不是教程&#xff0c;只是学习记录&#xff0c;方便后面回顾&#xff0c;代码均是100%可以运行成功的。 1. 渐变三角形 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <cmath>void framebuffer_size_callba…

代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗

前言:动态规划基础 动态规划首先可以解决的问题有背包问题,打家劫舍问题,股票问题,子序列问题等,主要是将一个大的问题切分成多个重叠的子问题,所以动态规划一定是上一个状态递推过来的,有一个重要的状态转移方程,但是这也并不是解题的全部,我们将动态规划的题目基本分为五步来…

【Kubernetes部署】二进制部署单Master Kurbernetes集群 超详细

二进制部署K8s 一、基本架构和系统初始化操作1.1 基本架构1.2 系统初始化操作 二、部署etcd集群2.1 证书签发Step1 下载证书制作工具Step2 创建k8s工作目录Step3 编写脚本并添加执行权限Step4 生成CA证书、etcd 服务器证书以及私钥 2.2 启动etcd服务Step1 上传并解压代码包Step…

Git客户端软件 Tower mac中文版特点说明

Tower mac是一款Mac OS X系统上的Git客户端软件&#xff0c;它提供了丰富的功能和工具&#xff0c;帮助用户更加方便地管理和使用Git版本控制系统。 Tower mac软件特点 1. 界面友好&#xff1a;Tower的界面友好&#xff0c;使用户能够轻松地掌握软件的使用方法。 2. 多种Git操…

Redis之持久化(RDB和AOF)

文章目录 前言一、RDB1.介绍2.redis.config有关配置3.触发4.恢复5.优缺点 二、AOF1.介绍2.redis.config配置3.启动4.恢复5.重写6.优缺点 总结 前言 Redis 是内存数据库&#xff0c;即数据存储在内存。 如果不将内存中的数据保存到磁盘&#xff0c;一旦服务器进程退出&#xff…

2023年科技革新:引领行业走向未来的十大技术趋势

随着时间的推移&#xff0c;2023年展现出了科技领域的一系列令人瞩目的新发现和趋势。这些新兴技术不仅推动了各行各业的发展&#xff0c;还为解决当今社会面临的诸多挑战提供了新的视角和解决方案。在这篇文章中&#xff0c;我们将探讨一些可能会改变行业面貌的关键技术趋势。…

arcgis图上添加发光效果!

看完本文, 你可以不借助外部图片素材, 让你的图纸符号表达出你想要的光! 我们以之前的某个项目图纸为例,来介绍下让符号发光的技术! 第一步—底图整理 准备好栅格影像底图、行政边界的矢量数据,确保“数据合适、位置正确、边界吻合”。 确定好图纸的大小、出图比例、投…