环形缓冲RingBuffer和无锁

环形缓冲

环形缓冲区,也被称为循环缓冲区或者环形队列,是一种数据结构类型,它在内存中形成一个环形的存储空间。环形缓冲区的特点是其终点和起点是相连的,形成一个环状结构。这种数据结构在处理流数据和实现数据缓存等场景中具有广泛的应用。

环形缓冲区的主要作用是存储和管理数据。它可以存储一定数量的数据,并且在数据存储满后,新的数据会覆盖最早的数据,从而实现了一种“先进先出”(FIFO)的数据管理方式。这种数据结构的优点是可以高效地利用有限的缓存空间,避免内存碎片,并且可以在多线程环境中实现数据的同步处理。熟悉Linux内核的读者应该对KFIFO并不陌生,详细的内容可以参考此篇文章链接: KFIFO.

typedef struct
{uint8_t* buff; //缓冲区uint16_t size; //缓冲区大小  uint16_t* read_ptr; //读指针     uint16_t* write_ptr; //写指针 
} RingBuffer;

缓冲区是满、或是空,都有可能出现读指针与写指针指向同一位置,有多种策略用于检测缓冲区是满、或是空。常用的做法是总是保持一个存储单元为空,缓冲区中总是有一个存储单元保持未使用状态。缓冲区最多存入 size-1个数据。如果读写指针指向同一位置,则缓冲区为空。如果写指针位于读指针的相邻后一个位置,则缓冲区为满。这种策略的优点是简单、鲁棒;缺点是语义上实际可存数据量与缓冲区容量不一致,测试缓冲区是否满需要做取余数计算。

无锁

在多线程环境中,如果有多个写线程,那必然是要加锁的。但是,对于单生产单消费模式(即一个线程只读一个线程只写)则无需加锁。

对于单线程读单线程写一个变量,一般来说是要加锁的,以避免写变量的非原子性操作,导致读线程读出中间态的数据。

对于简单数据类型(int、bool等)的多线程读写安全性跟CPU架构相关。在x86上,对1字节byte/2字节word/4字节int类型的读写操作都是原子性的。即1个int不会有中间状态,若它原始值是0,往其写入0x12345678,则另一个线程绝对不会读到0x12000000或是0x00005678的值。在64位x86上,size_t(8字节)也是原子操作(多核,volatile)。

对于变量需要进行一些计算的情况,如a = a + 1,这个操作毫无疑问肯定不是原子操作。这个语句简单的转换为类似机器语言,第一步,把a读取到一个寄存器中,第二步将寄存器中的值加1,第三步将寄存器中的新值写入a中。线程B要写a,做了三步操作中任何一步结束,线程A去读a,a仍是一个有效值,只不过a并不一定是一个最新的值。如果线程A并不关心a是不是最新的值,只关心a是否是一个合法值就可以了,至于最新值可以通过循环去不断刷新。因为有了字节对齐,一个读周期或是一个写周期仅需要一个总线周期,在这个总线周期内就把这个整型变量给处理了, 一个总线周期结束前CPU不会被抢占,就是中断发生也不会导致一个总线周期执行一半时CPU被抢占(CPU是在现行指令结束后响应中断,即运行到最后一个指令周期中的最后一个总线周期中的最后一个T状态时CPU才采样INTR线来查看是否有中断请求)。

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

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

相关文章

【MySQL】内置函数——日期函数

函数名称描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime的日期部分date_add(date,interval d_value_type)在date中添加日期或时间。interval后的数值可以是:year,day,minute&…

【Linux升级之路】7_进程信号

目录 一、【Linux初阶】信号入门 | 信号基本概念信号产生核心转储二、【Linux初阶】信号入门2 | 信号阻塞、捕捉、保存 一、【Linux初阶】信号入门 | 信号基本概念信号产生核心转储 链接: 【Linux初阶】信号入门 | 信号基本概念信号产生核心转储 二、【Linux初阶】…

java学习--day22(进程线程)

文章目录 1.什么是进程2.什么是线程3.线程和进程的区别【面试题】4.并发和并行5.创建线程的两种方式【重点】1.继承Thread2.实现Runnable接口 6.线程下面的几个方法7.线程的同步和锁【重要】 1.什么是进程 是独立的运行程序 ​ 比如咱们电脑软件,你启动起来以后&…

Ubuntu LabelMe AI 识别

1.创建虚拟环境 conda create -n labelme python3.9 2.激活虚拟环境 conda activate labelme 3.安装labelme pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple pip install labelme -i ht…

【数据结构-字符串 三】【字符串转换】字符串解码

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【字符串转换】,使用【字符串】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

RPC分布式网络通信框架项目

文章目录 对比单机聊天服务器、集群聊天服务器以及分布式聊天服务器RPC通信原理使用Protobuf做数据的序列化,相比较于json,有哪些优点?环境配置使用项目代码工程目录vscode远程开发Linux项目muduo网络库编程示例CMake构建项目集成编译环境Lin…

【计算机网络黑皮书】传输层

【事先声明】 这是对于中科大的计算机网络的网课的学习笔记,感谢郑烇老师的无偿分享 书籍是《计算机网络(自顶向下方法 第6版)》 需要的可以私信我,无偿分享,课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…

Linux 指令心法(十)`head` 显示文本文件的开头部分

文章目录 命令的概述和用途命令的用法命令行选项和参数的详细说明命令的示例命令的注意事项或提示 命令的概述和用途 head 是一个用于显示文本文件的开头部分的命令。它在 Linux 和 Unix 系统中非常有用,因为它允许用户查看文件的前几行,以便快速预览文…

常见排序算法Java版(待续)

冒泡排序O(n^2) public class Main {public static void main(String[] args) {Random random new Random();int[] nums new int[]{random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100)};for (i…

英特尔参与 CentOS Stream 项目

导读红帽官方发布公告欢迎英特尔参与进 CentOS Stream 项目,并表示 “这一举措不仅进一步深化了我们长期的合作关系,也构建在英特尔已经在 Fedora 项目中积极贡献的基础之上。” 目前,CentOS Stream 共包括以下特别兴趣小组(SIG&a…

汽车冲压车间的RFID技术设计解决方案

一、RFID技术的基本原理 RFID技术是一种利用非接触式自动识别的技术,通过将RFID标签放置在被识别物品上,并使用RFID读写器对标签进行扫描和识别,实现对物品的自动识别和追踪。RFID标签分为被动式和主动式两种。被动式标签无内置电源&#xf…

23.3 Bootstrap 框架4

1. 轮播 1.1 轮播样式 在Bootstrap 5中, 创建轮播(Carousel)的相关类名及其介绍: * 1. carousel: 轮播容器的类名, 用于标识一个轮播组件. * 2. slide: 切换图片的过渡和动画效果. * 3. carousel-inner: 轮播项容器的类名, 用于包含轮播项(轮播图底下椭圆点, 轮播的过程可以显…

HTTP协议的请求协议和响应协议的组成,HTTP常见的状态信息

HTTP协议 什么是协议 协议实际上是某些人或组织提前制定好的一套规范,大家只要都按照这个规范来就可以做到沟通无障碍 HTTP协议是W3C(万维网联盟组织)制定的一种超文本传输通信协议(发送消息的模板和数据的格式),除了传送字符串,还有声音、视频、图片等流媒体等超文本信息 …

ctfshow-web11(session绕过)

php代码审计: function replaceSpecialChar($strParam){$regex "/(select|from|where|join|sleep|and|\s|union|,)/i";return preg_replace($regex,"",$strParam);} 首先定义了一个函数,主要是使用preg_replace函数对我们提交的内…

拟合平面再思考

0。总结 之前思考了2种拟合平面的方式 1。ransan 随机取样拟合平面 2。特征值分解特征向量,最小特征值就是法向量 其中方法一误差较小,毕竟随机采样的方式可以忽略误差点。而特征值分解的方式如果误差较大,那么得到的结果非常不好 1。扩展…

SpringBoot的创建和使用

优点 快速添加依赖; 内置web容器; 自动装配; idea创建 创建maven项目(配置) 一定要选择2.x版本的Spring Boot 介绍目录 (有这个注解的SpringBootApplication就是启动类) 删除文件 尝试去运行带有SpringBootApplica…

面向对象设计-UML六种箭头含义

目录 UML概述UML语义UML表示法 六种常用关系标识方法泛化实现依赖关联聚合组合 本文参考文章 https://blog.csdn.net/qq_25091281/article/details/123801862 UML概述 UML (Unified Modeling Language)为面向对象软件设计提供统一的、标准的、可视化的建模语言。适用于描述以…

数学分析:含参变量的积分

同样很多收敛性的证明不是重点,但里面的知识还是需要适当掌握,知道中间的大致思考和解决路径即可。 本质还是极限的可交换性,求导可以换到积分里面去操作。 这里要注意变量的区别,首先积分的被积变量是x,但是函数的变量…

springsecurity

springsecurity 一个安全框架,例如:在进行登录之前,会进行一个拦截,经过安全框架之后,才会跳转到原本要登录的地址 culr:(不细写,需另找文档) 可以进行登录的操作(在git…

git 详解-提升篇

git 冷门使用 承接上一篇 《git 进阶篇》,简单讲解 git 冷门使用方法。 码农常规使用工具 git 偶尔也有非常规操作。例如:提交代码时同事已经更新,但又不想回退本地补丁;或者已经提交补丁需要变更提交日志信息。 作者&#xff1…