无锁队列ringbuff实现以及性能

news2024/11/25 12:50:12

文章目录

    • 一、使用场景
    • 二、对比有锁优势
    • 三、无锁队列实现方式
    • 四、循环队列实现
      • 1)数据结构设计
      • 3)代码实现
      • 4)性能测试
      • 5)总结

一、使用场景

无锁队列主要适用于高并发场景或者对性能要求较高的场景,主要使用场景有如下几个方面:

  1. 并发任务处理:当有多个线程或者进程需要并发地向队列中添加或者取出数据时,无锁队列可以提供高吞吐量和低延迟的性能。
  2. 生产者-消费者模型:在生产者-消费者模型中,生产者将数据放入队列,消费者从队列中取出数据进行处理。无锁队列可以提供高效的数据交换机制,使得生产者和消费者之间能够实现高并发的数据交互。
  3. 事件驱动系统:在事件驱动的系统中,事件源会将事件放入队列,事件处理器从队列中取出事件并进行处理。无锁队列能够提供高效的事件处理机制,使得系统能够快速响应事件。
  4. 高性能网络通信:在网络通信中,消息的发送和接收往往需要经过队列进行中转。无锁队列可以提供高吞吐量和低延迟的消息传递机制,使得网络通信能够更高效地进行。

以上场景对于有锁队列和无锁队列都可以使用的,但还如果对性能要求比较高,比如需要达到上万ops,就可以考虑优先使用无锁队列。相反如果性能达不到这么高使用有锁队列和无锁队列性能差别并不大,但是有锁队列实现会更加简单。

二、对比有锁优势

  1. 并发性能更好:无锁队列通过使用原子操作和CAS(比较并交换)等技术,在并发访问时不需要使用锁,避免了锁竞争上下文切换的开销,从而能够提供更高的并发性能。
  2. 延迟更低:由于无锁队列不需要等待锁的释放,可以避免线程阻塞,从而减少了任务等待的时间,提高了任务的响应速度和系统的吞吐量。
  3. 无死锁风险:有锁队列在并发环境中容易出现死锁问题,而无锁队列没有锁的概念,因此不会出现死锁的风险。

三、无锁队列实现方式

  • 链表
  • 数组(循环队列—ringBuff)
  • 数组 + 链表

本文采用的是循环队列的实现方式。

四、循环队列实现

1)数据结构设计

在这里插入图片描述

队列维护三个指针,通过这三个指针来实现数据的压入、弹出操作:

  • read:指向对头第一个元素, pop位置
  • readMax:指向队尾的下一个元素位置
  • write:指向当前可以向队列写入数据的位置,push位置

队列中的数据分为两种:

  • 写入中(黄色Data):该数据当前还没有完全写入队列,对读不可见,不能读取,位于队列尾部;
  • 已写入(红色Data):该数据已经写入完成,可以直接读取;

队列判空条件:read == readMax

队列已满条件:write + 1 == read

readMax到write之间的数据这样设计可以保证并发时未完全插入的数据不会被消费者线程看到。

3)代码实现

github:https://github.com/yangziju/freeLockQueue

4)性能测试

以同样的数据结构(环形队列)实现一个有锁的队列,进行对比测试,两者的区别就在于一个加锁一个无锁,消费者在取出数据后会进行1000 次 empty loop。

测试环境:

系统:Debian x86_64虚拟机,4核4G

测试模型1:

  • Producer:1
  • Consumer:1
  • 数据量:一千万
  • 消费者线empty loop:0

测试结果如下:

在这里插入图片描述

测试模型2:

  • Producer:1
  • Consumer:1
  • 数据量:一千万
  • 消费者线empty loop:1000

测试结果如下:
在这里插入图片描述

测试模型3:

  • Producer:1
  • Consumer:3
  • 数据量:一千万
  • 消费者线empty loop:1000

测试结果如下:
在这里插入图片描述

测试模型4:

  • Producer:3
  • Consumer:1
  • 数据量:一千万
  • 消费者线empty loop:1000

测试结果如下:
在这里插入图片描述

测试模型5:

  • Producer:2
  • Consumer:2
  • 数据量:一千万
  • 消费者线empty loop:1000

测试结果如下:

在这里插入图片描述

5)总结

测试结果分析可以知道:

  • 多写一读:无锁队列性能不入有锁队列。
  • 一写多读:随着读(消费者)线程数量增加,无锁和有锁队列性能都会下降,最后无锁队列性能还是不入有锁队列。
  • 消费者线程处理数据越久,无锁队列性能更优。

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

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

相关文章

pytorch的permute(dims) 函数的功能详解

有三块 二维矩阵 如下 把二维矩阵堆叠起来,就是三维 矩阵 这样的矩阵 从x方向看(0维) 有三块 记为3,每块从y方向看(1维)的行是3,从z方向看(2维)列也是3,故三…

计算机中丢失mfc140.dll怎么解决?mfc140.dll是什么文件?

在计算机运行软件或者游戏的时候,提示mfc140.dll丢失,无法正常启动运行。 mfc140.dll是Windows操作系统中用于支持C编程语言的一个动态链接库,它包含了C运行时库的一些基本功能。用于支持Microsoft Visual Studio的MFC(Microsoft …

论文解读:FastSAM | Fast Segment Anything | 基于yolov8-seg实现 比SAM快50倍

发表时间:2023.06.21 论文地址:http://export.arxiv.org/pdf/2306.12156 项目地址:https://github.com/CASIA-IVA-Lab/FastSAM 最近提出的任意分割模型(SAM)在许多计算机视觉任务中产生了重大影响。它正在成为许多高级…

NIO总结

简要介绍 NIO(Non-blocking IO)是Java 1.4版本开始引入的一个新的IO API,旨在代替传统IO,它引入了缓冲区和通道的概念,通过选择器实现多路复用。 传统IO会区分字节流InputStream和OutputStream以及字符流Reader和Wri…

GD32 时钟和晶振修改

芯片型号:gd32f470zi 库版本:GD32F4xx_Firmware_Library_V3.0.4 当需要修改外部晶振和主频时需要修改到以下几个地方 1.gd32f4xx.h //此宏定义为我们实际使用的外部晶振频率,此处改为实际使用的25M #define HXTAL_VALUE ((uint32_t)2…

单片机学习 13-I2C_EEPROM

I2C-EEPROM 实验 ​ 这一章我们来学习如何使用 51 单片机的 IO 口模拟 I2C 时序,并实现与AT24C02(EEPROM)之间的双向通信。开发板板载了 1 个 EEPROM 模块,可实现IIC 通信。本章要实现的功能是:系统运行时&#xff0c…

如何排查 Electron V8 引发的内存 OOM 问题

经过长达大半年时间的崩溃治理后,基于 Electron 框架开发的新版 PC 淘宝直播推流客户端的稳定性终于赶超基于QT 框架开发的旧版本了。剩下的崩溃问题中有 40% 是跟内存 OOM 有关,其中 V8FatalErrorCallback js heap OOM 问题整整困扰了我一个多月。历经千…

Pytorch--模型微调finetune--迁移学习 (待继续学习)

https://www.bilibili.com/video/BV1Z84y1T7Zh/?spm_id_from333.788&vd_source3fd64243313f29b58861eb492f248b34 主要方法 torchvision 微调timm 微调半精度训练 背景(问题来源) 解决方案 大模型无法避免过拟合,

嵌入式综合性开源项目分享

不定期有小伙伴问: 哪里有好的嵌入式项目? 怎么才能提高编程水平? 有实战项目可以分享一下吗? 目录 第一:嵌入式综合Awesome Embedded 第二:多功能按键MultiButton 第三:软件定时器模块M…

计算机网络学习笔记-应用层

目录 概述 客户-服务器方式(C/S) 对等方式(P2P) 域名系统DNS 域名 四种类型 根域名服务器 顶级域名服务器 权限域名服务器 本地名服务器 域名解析过程 万维网WWW 超媒体与超链接 工作方式 URL(统一资源…

Spring Boot 中的 WebSocketMessageBrokerConfigurer

Spring Boot 中的 WebSocketMessageBrokerConfigurer 在现代 Web 应用程序中,WebSocket 已成为一种流行的通信协议,它允许客户端和服务器之间实时双向通信。在 Spring Boot 中,我们可以使用 WebSocketMessageBrokerConfigurer 接口来配置 We…

vivo 自研鲁班分布式 ID 服务实践

作者:vivo IT 平台团队- An Peng 本文介绍了什么是分布式ID,分布式ID的业务场景以及9种分布式ID的实现方式,同时基于vivo内部IT的业务场景,介绍了自研鲁班分布式ID服务的实践。 一、方案背景 1.1 分布式ID应用的场景 随着系统的…

【Servlet】HttpServletRequest、HttpServletResponse

目录 🎁1 HttpServletRequest 💥1.1 通过 query string 来进行传递 🐷1.2 通过 body (form) 来进行传递 🛸1.3 通过 body(json) 来进行传递 🍘2. HttpServletResponse 👶2.1 为响应设置状态码 200 …

JVM 常量池

一、常量池使用 的数据结构 常量池底层使用HashTable key 是字符串和长度生成的hashValue,然后再hash生成index, 改index就是key;Value是一个HashTableEntry; 1、key hashValue hash string(name, len) index hash to…

LeetCode 打卡day48--打家劫舍I, II, III

一个人的朝圣 — LeetCode打卡第48天 知识总结 Leetcode 198. 打家劫舍题目说明代码说明 Leetcode 213. 打家劫舍 II题目说明代码说明 Leetcode 337. 打家劫舍 III题目说明代码说明 知识总结 今天全是打家劫舍系列的题目, 还挺有意思的 Leetcode 198. 打家劫舍 题目链接 题目…

SpringBoot配置

1.配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的; application.propertiesapplication.yml 配置文件的作用:修改SpringBoot的自动配置的默认值;SpringBoot在底层都给我们自动配置好; YAML 是一个标记语言;不是…

一步一步学OAK之三:实现RGB相机场景切换

目录 Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 遍历所有场景模式和特效模式Setup 5: 创建pipelineSetup 6: 创建节点Setup 7: 连接设备并启动管道Setup 8: 创建与DepthAI设备通信的输入队列和输出队列Setup 9: 定义putText函数Setup 10: 主循环获取视…

SpringBoot3【① 快速入门 示例+基本框架】

SpringBoot3-特性介绍和快速入门 1、简介 1. 前置知识 Java17Spring、SpringMVC、MyBatisMaven、IDEA 2. 环境要求 环境&工具版本(or later)SpringBoot3.0.5IDEA2021.2.1Java17Maven3.5Tomcat10.0Servlet5.0GraalVMCommunity 22.3Native Build …

2-NumPy如何使用?【视频版】

目录 问题视频解答 问题 视频解答 点击观看: 2-NumPy如何使用?

TypeScript学习(一):快速入门

文章目录 一、TypeScript 简介1、TypeScript 是什么?2、TypeScript 与 JavaScript 的区别3、JavaScript 的缺点4、为什么使用 TypeScript 二、TypeScript 开发环境搭建1、下载Node.js2、安装Node.js3、使用npm全局安装TypeScript4、创建一个ts文件5、使用tsc对ts文件…