高效无锁环形队列

HeroKern HeroKern     2022-11-29     681

关键词:

在linux零拷贝技术中提到高效无锁环形队列,这篇文章分享这个知识点,这个知识点不是很复杂。环形队列多用于多线程之间数据异步传输,提高数据处理性能。下面介绍常规环形队列和高效无锁队列两种处理方式。
常规环形队列如下图所示,队列头代表写指针,队列尾代表读指针,通过判断读写的位置判断队列是否为空,是否满,通过线程锁来保证读写指针在使用时只被一个线程使用,从而保证数据不会出错。(出错原因,当一个线程在对读写指针修改时,调度器将该线程切换出去访问另外一个线程,如果该线程正好也会对读写指针进行修改,那么就会导致读写指针被污染而不能继续使用)。

环形队列初始化代码如下:

读写指针相等代表队列为空,写指针加一等于读指针代表队列未满,这里需要注意队列缓存从尾部跳转到头部这个临界值需要单独处理。
读队列处理函数如下图所示。读取队列首先应该判断该队列是否为空,如果没有数据就休眠等待有数据,有数据就取出数据并且让读指针加一,加满到队列大小后就重新从0位置开始。
注意:pthread_cond_wait这里不存在死锁情况,该函数内部为自动调用pthread_mutex_unlock函数进行解锁。当等到pthread_cond_signal该信号时候就退出休眠自动调用pthread_mutex_lock函数上锁。

环形队列写函数如下所示。需要对队列操作时需要上锁,然后判断队列是否未满,如果队列满了就退出,未满就可以向队列中写数据,同时写指针加一,同时出发条件变量信号。注意:pthread_cond_signal和pthread_cond_wait函数不需要一一对应,及时没有进入pthread_cond_wait等待状态,也不影响pthread_cond_signal函数,pthread_cond_signa不存在累计的情况。
以上就是常规环形队列处理方式,pthread_mutex_lock函数是阻塞方式获取锁,比较耗时效率相对低。

高效无锁队列
高效无锁队列与环形队列思想基本一致,只是去掉了互斥锁部分,引入了标志位。高效无锁队列如下所示。

队列分布于常规队列一致,在队列每项前面添加了一个标志位,就是图中红色部分,标志位 用于判断该像目前的状态,一共有可以写(CAN_WRITE),可以读(CAN_READ),正在读(READING),正在写(WRITING)四种状态。
初始化如下所示。代码思想比较简单就不在讲解代码了。

取数据函数如下所示。

写数据函数如下所示。写数据之前需要判断是否有可以写的地址,以阻塞方式去取写地址。

给队列写数据就需要去获取可用的队列地址,阻塞方式获取到可以使用的队列地址,同时让下指针加一,读队列会去判断队列是否有数据。该方式判断是通过标志位进行判断的,这种方式在实际使用场景比较多,特别裸奔程序中(就是不上系统,像单片机程序)。

总结
本文分享了常规环形队列和高效无锁队列,这两种方式在实际应用中比较多,有需要技术支持的联系:yolov8。

高效无锁环形队列

在linux零拷贝技术中提到高效无锁环形队列,这篇文章分享这个知识点,这个知识点不是很复杂。环形队列多用于多线程之间数据异步传输,提高数据处理性能。下面介绍常规环形队列和高效无锁队列两种处理方式。... 查看详情

高效无锁环形队列

在linux零拷贝技术中提到高效无锁环形队列,这篇文章分享这个知识点,这个知识点不是很复杂。环形队列多用于多线程之间数据异步传输,提高数据处理性能。下面介绍常规环形队列和高效无锁队列两种处理方式。... 查看详情

环形队列高效触发大量超时任务的算法实现

基于环形队列的超时触发算法只需要一个timer即可实现批量超时任务的触发,CPU消耗低,效率高。下面是此算法的简单实现。1,TaskHolder.javapackage com.zws.timer;/** *  * @author wensh.zhu * @date 2018-04-22 ... 查看详情

cas无锁队列的实现(代码片段)

文章目录1.基本原理2.代码实现2.1使用链表实现无锁队列2.2使用数组实现环形无锁队列3.ABA问题及解决4.参考资料1.基本原理源于1994年10月发表在国际并行与分布式会议上的论文【无锁队列的实现.pdf】。CAS(CompareAndSwap,CAS... 查看详情

环形队列-高效定时触发

参考技术A为了实现高效延时触发,我们需要实现两个重要的数据结构:(1)环形队列,例如可以创建一个包含3600个slot的环形队列(本质是个数组)(2)任务集合,环上每一个slot是一个Set<Task>同时,启动一个timer,这个time... 查看详情

每日一博-使用环形队列实现高效的延时消息(代码片段)

文章目录Pre方案A方案B总结Pre来个场景:24小时后将未进行某个Action的业务,执行另外一个动作。比如24小时未付款的订单,取消。你可能会说方案A来个定时呗,每隔半小时,扫描数据库订单表,将完成时... 查看详情

什么是环形队列,采用什么方法实现环形队列

...分配,使用固定大小的内存空间反复使用。非常的简单和高效本回答被提问者采纳 查看详情

多线程编程之无锁队列

关于无锁队列的概念与实现,可以参考博文《无锁队列的实现》,主要涉及到的知识点包括CAS原子操作、无锁队列的链表实现、无锁队列的数组实现以及ABA问题。  下面借鉴了《多线程的那点儿事(之无锁队列)》的代码,说... 查看详情

无锁队列的实现

...是在某些特殊的场景下,是可以通过优化数据结构来达到无锁的目的。那么我们就来看一下如何实现一个无锁队列。队列:众所周知,就是先进先出。出队列的时候从队列头取出一个结点;入队列的时候,将结点添加到队列尾部... 查看详情

数据结构(10)---队列之环形队列(代码片段)

环形队列文章目录环形队列什么是环形队列循环队列的实现第一种实现第二种实现什么是环形队列环形队列也是队列的一种数据结构,也是在队头出队,队尾入队;只是环形队列的大小是确定的,不能进行一个长度的增加,当你把一个... 查看详情

没有原子的 SPSC 无锁队列

】没有原子的SPSC无锁队列【英文标题】:SPSClockfreequeuewithoutatomics【发布时间】:2014-11-2600:20:48【问题描述】:我的记录器有一个SPSC队列。它肯定不是一个通用的SPSC无锁队列。但是,考虑到关于如何使用、目标架构等的一系列... 查看详情

无锁队列

1伪命题这本身是个伪命题。多线程之间使用队列是一定需要做到同步的。也就是说一定是需要同步手段的,一定要在一个线程读写的时候,阻塞另一个线程。既然不然用锁,那就是用原子变量吧。 2CAS3实现队列,这里使用链... 查看详情

高性能并发队列disruptor(代码片段)

...性能的异步处理框架,是一个轻量的Java消息服务JMS,能够在无锁的情况下实现队列的并发操作Disruptor使用环形数组实现了类似队列的功能,并且是一个有界队列.通常应用于生产者-消费者的场景Disruptor是一个观察者模式的实现Disruptor... 查看详情

并发无锁队列

1、前言    队列在计算机中非常重要的一种数据结构,尤其在操作系统中。队列典型的特征是先进先出(FIFO),符合流水线业务流程。在进程间通信、网络通信之间经常采用队列做缓存,缓解数据处理压力。结合自己在工... 查看详情

原子操作实现无锁队列

关于CAS等原子操作在开始说无锁队列之前,我们需要知道一个很重要的技术就是CAS操作——Compare&Set或是Compare&Swap,现在几乎所有的CPU指令都支持CAS的原子操作,X86下对应的是 CMPXCHG 汇编指令。有了这个原子... 查看详情

C++ 无锁队列

】C++无锁队列【英文标题】:C++Lock-FreeQueue【发布时间】:2020-07-2616:04:49【问题描述】:我设计了这个函数,用来实现Lock-Free队列,但是在实际执行过程中(dequeue)存在死锁问题。我检查了很多次,我认为这很好。我在x86平台上运... 查看详情

如何在无锁并发队列中实现“Front”方法?

】如何在无锁并发队列中实现“Front”方法?【英文标题】:Howtoimplement"Front"methodinalock-freeconcurrentqueue?【发布时间】:2019-11-2523:54:18【问题描述】:我正在尝试实现一个并发无锁队列。我正在密切关注这篇论文:https://www... 查看详情

c语言之环形队列(代码片段)

. 一、环形队列的优势环形队列是一种特殊的队列,它可以解决普通队列在使用时空间利用不充分的问题。在环形队列中,当队列满时,队列的尾指针指向队列的起始位置,而不是指向队列的最后一个元素。这样可以在不浪... 查看详情