当前位置: 首页 > news >正文

Iceoryx(冰羚):无锁队列与并发控制的设计与实现4(源码解析)

接上篇

总结一下1~3篇

设计1: SpscFifo(Single Producer Single Consumer First In Fisrt Out)

设计2: SpscSofi (Single Producer Single Consumer Stack Overflow Fisrt In First Out)

https://blog.csdn.net/hanyuan1993/article/details/159386614

设计3: MpmcLockFreeQueue (Multiple Producer Multiple Consumer)

https://blog.csdn.net/hanyuan1993/article/details/159424230

设计4: 索引管理层( MpmcIndexQueue / CyclicIndex)

https://blog.csdn.net/hanyuan1993/article/details/159462305?spm=1001.2014.3001.5502

这3篇文章分析的都是Subscriber的Queue的实现,使用场景在这里也再总结一下:

  • SpscFifo:单生产者单消费者,满等待
  • SpscSofi:单生产者单消费者,满覆盖
  • MpmcLockFreeQueue:多生产多消费者,可以满等待也可以满覆盖
  • MpmcIndexQueue / CyclicIndex:MpmcLockFreeQueue 的索引层,解决了多生产者情况下的索引竞争问题(ABA)

但是concurrent里面还有一个MpmcLoFFLi实现没有说,这篇会解析完~~

补充 设计5: MpmcLoFFLi

Mempool的内存池管理,也是用索引和数据分离的方案来减少竞争,是维护了一个索引栈。与Subscriber的Queue不同,Subscriber取数据需要保留先进先出的顺序,但是Mempool不需要顺序执行

数据结构:

Mempool的使用场景是,多进程pop拿到唯一的index,多进程push唯一的index;其实MpmcLockFreeQueue的设计也能满足Mempool的需求。但是Iceoryx(冰羚)的设计精妙的点在于利用了链表的结构。

  • 如果使用普通的栈结构,则无法区分栈中存放的数据,栈里面可能是2221222,但索引栈里的数据只能唯一,即使是乱序,也应该只有一份,比如(2360145)。
  • 链表很好的利用了数组的下标唯一的特点链表状态下,push两个不同的index,存放的是数组[index1] 和数组[index2] 不会是同一块内存。(具体看例子理解)

Iceoryx(冰羚)的实践:数组先维护成链表,然后再由head来指向栈顶。

维护的成员变量:
m_head:indexToNextFreeIndex + abacounter

(指向栈顶, abacounter保证 CAS时不会出现 ABA 问题)

m_nextFreeIndex:数组

(从head中的indexToNextFreeIndex开始,将数组形成一张链表)

m_invalidIndex:11

(以下例子的假设数据)

m_size:10

(以下例子的假设数据)

m_head初始化:0 + 0
m_nextFreeIndex 初始化后:

12345678910
[0][1][2][3][4][5][6][7][8][9]

使用了[0], [1], [2], [3] 后:

m_head:indexToNextFreeIndex(4) + abacounter(4)

m_nextFreeIndex 当前状态:

111111115678910
[0][1][2][3][4][5][6][7][8][9]

假设先还回来0:

m_head:indexToNextFreeIndex(0) + abacounter(5)

m_nextFreeIndex 当前状态:

41111115678910
[0][1][2][3][4][5][6][7][8][9]

假设再还回来2:

m_head:indexToNextFreeIndex(2) + abacounter(6)

m_nextFreeIndex 当前状态:

4110115678910
[0][1][2][3][4][5][6][7][8][9]

此时pop,index为2:

m_head:indexToNextFreeIndex(0) + abacounter(7)

m_nextFreeIndex 当前状态:

41111115678910
[0][1][2][3][4][5][6][7][8][9]

pop逻辑:

  • 移动 head > new_head (CAS + ABA)
  • 拿出 head里面的index
current_head = m_head.load() do { new_head = m_nextFreeIndex[current_head.index] new_head.abacounter = current_head.abacounter + 1 } while(m_head.compare_exchange(current_head, new_head)) index = current_head.indexToNextFreeIndex current_head.index = m_invalidIndex

push逻辑:

  • 先建立 m_nextFreeIndex 队列中,当前index的值的链接 m_nextFreeIndex[index] = head.indexToNextFreeIndex
  • 创建 new_head
  • 移动 head > new_head (CAS, ABA)
current_head = m_head.load() do { m_nextFreeIndex[index] = current_head.indexToNextFreeIndex new_head.index = index new_head.abacounter = current_head.abacounter + 1 } while(m_head.compare_exchange(current_head, new_head))

MpmcLoFFLi、MpmcLockFreeQueue 对比:

poppush
MpmcLockFreeQueuem_freeIndices有空闲,则竞争m_freeIndices中的 r;队列满时,竞争m_usedIndices中的 r 指针需要先竞争cells[w] 的写权限,w指针的更新也存在竞争
MpmcLoFFLi竞争head竞争head

链表这个设计确实很精妙~学到了~

http://www.jsqmd.com/news/563399/

相关文章:

  • ESP32/ESP8266嵌入式IoT工具库:轻量、可靠、生产就绪
  • 避坑指南:在Ultralytics YOLOv8中正确使用VarifocalLoss的两种方法(附GitHub Issues解决方案)
  • 深求·墨鉴HTTPS配置:Nginx反向代理,安全访问OCR工具
  • BTS4140N:智能高侧电源开关在汽车电子中的关键应用与保护机制解析
  • C 程序设计数组核心知识点梳理
  • Z-Image-Turbo模型微调:LoRA技术实战指南
  • Cursor API限制突破架构设计与系统实现方案
  • 抖音下载神器:5分钟掌握无水印批量下载完整方案
  • Qwen3-Max LeetCode 964.表示数字的最少运算符 public int leastOpsExpressTarget(int x, int target)
  • PTA数据结构刷题笔记:用C语言手撕奥运排行榜(附完整代码与避坑指南)
  • 一文读懂:库存管理方法有哪些?主流方案深度汇总
  • 《QGIS快速入门与应用基础》248:对齐工具(左对齐/居中对齐/右对齐)对齐工具(左对齐/居中对齐/右对齐)对齐工具(左对齐/居中对齐/右对齐)对齐工具(左对齐/居中对齐/右对齐)对齐工具(左对齐/
  • Qwen3-0.6B-FP8多场景:教育问答、IT支持、内容摘要三类POC验证
  • HarmonyOS6 ArkTS 创建ListItem
  • 小白也能做!我用Python写了一个带AI语音的美食菜单系统✨
  • 【OSG学习笔记】Day 22: StateSet 与 StateAttribute (渲染状态)
  • 你的音量滑块科学吗?从人耳听觉原理到PCM对数音量调节实战
  • 告别乱码:Matlab脚本中文注释编码冲突的实战排查与修复
  • B2B战略到营销分解实战:OGSM / 主题 / 内容 / 渠道 / 节奏五层框架
  • 麦克风效率革命:MicMute让静音操作提速90%的终极体验升级
  • 数据结构之队列(Queue)
  • Blender 3MF插件终极指南:轻松处理3D打印文件的完整教程
  • Yi-Coder-1.5B数据库管理实战:MySQL安装配置与优化
  • ARZOPA便携屏接电脑,频繁黑屏的问题解决
  • ssm+java2026年毕设停车场管理系统【源码+论文】
  • 如何用OpenRGB终结RGB灯光控制混乱:终极跨平台解决方案
  • DFRobot_SIM库解析:AT指令抽象层设计与嵌入式通信实践
  • Apache James邮件服务器:企业级邮件系统的构建与运维指南
  • 物联网项目-------配置模块以及XML,单例模式
  • Nano vLLM推理框架解析(schedule篇)