这里写目录标题

  • 1. DPDK Ring简介
  • 2. Ring实现
    • 2.1 单一生产者入队
    • 2.2 单一消费者出队
    • 2.3 多个生产者入队
    • 2.4 多个消费者出队
  • 3 总结
    • 3.1 入队列
    • 3.2 出队列

1. DPDK Ring简介

dpdk实现了一个无锁环形队列Ring,可用于在dpdk不同的应用程序之间进行通信。

逻辑上ring看起来如下图:

在使用这个结构的时候,一般是将1个核作为生产者,向这个ring队列里面添加数据;另一个core或者多个core 作为消费者从这个ring队列中获取数据。生产者核访问上面的prod结构,消费者访问cons结构。

Ring支持的效果:

  • 先进先出
  • 最大大小是固定的,指针存储在表中
  • 无锁实现
  • 多消费者或单消费者出队
  • 多生产者或单生产者入队
struct rte_ring {                                                                                                                            /* Ring producer status. */                                                                                struct prod {                                                                                                uint32_t watermark;     /**< Maximum itemsbefore EDQUOT. */                                             uint32_t sp_enqueue;    /**< True, if single producer. */                                                uint32_t size;          /**< Size of ring.*/                                                           uint32_t mask;          /**< Mask (size-1)of ring. */                                                   volatile uint32_thead;  /**< Producer head.*/                                                           volatileuint32_t tail;  /**< Producer tail.*/                                                           } prod __rte_cache_aligned;                                                 /* Ring consumer status. */                                                                                struct cons {                                                                                                uint32_t sc_dequeue;    /**< True, if single consumer. */                                                uint32_t size;          /**< Size of thering. */                                                       uint32_t mask;          /**< Mask (size-1)of ring. */                                                   volatileuint32_t head;  /**< Consumer head.*/                                                           volatileuint32_t tail;  /**< Consumer tail.*/                                                                                                                                      } cons __rte_cache_aligned;                                                                                  void*ring[] __rte_cache_aligned;  };

2. Ring实现

2.1 单一生产者入队

首先,将ring-> prod_head和ring-> cons_tail复制到局部变量中。prod_next局部变量指向表的下一个元素,或在批量入队的情况下指向多个元素。

如果环中没有足够的空间(通过检查cons_tail可以检测到),它将返回错误。

第二步是修改环结构中的ring-> prod_head以指向与prod_next相同的位置。
指向添加对象的指针将复制到环(obj4)中。

将对象添加到环中后,将修改环结构中的ring-> prod_tail使其指向与ring-> prod_head相同的位置。入队操作完成。

2.2 单一消费者出队

同上

2.3 多个生产者入队

在两个CPU core上,ring-> prod_head和ring-> cons_tail都复制到局部变量中。prod_next局部变量指向表的下一个元素,或者在批量入队的情况下指向多个元素。

如果环中没有足够的空间(通过检查cons_tail 与 prod_head 差值可以检测到)

第二步是修改ring结构中的ring-> prod_head以指向与prod_next相同的位置。此操作使用“比较并交换”(CAS)指令完成,该指令自动执行以下操作:

  • 如果ring-> prod_head与局部变量prod_head不同,则CAS操作失败,并且代码在第一步重新启动。
  • 否则,将ring-> prod_head设置为本地prod_next,CAS操作成功,然后继续处理。

在该图中,操作在内核1上成功完成,而第一步在内核2上重新启动。

成功在核心2上重试CAS操作。

核心1更新了ring(obj4)的一个元素,核心2更新了另一个(obj5)的元素。

每个内核现在都想更新ring-> prod_tail。仅当ring-> prod_tail等于prod_head局部变量时,内核才能更新它。这仅在内核1上成立。操作已在内核1上完成。

内核1更新了ring-> prod_tail之后,内核2也可以对其进行更新。该操作也在内核2上完成。

2.4 多个消费者出队

同上

3 总结

3.1 入队列

  1. 抢先更新头指针,此时头指针被更新为下一次入队列的起始位置,此时另外一个进程也是可以同时入队列的,只是要排队修改尾指针
  2. 然后放入数据
  3. 然后更新尾指针,其他进程排队更新尾指针

3.2 出队列

  1. 抢先更新头指针,此时头指针被更新为下一次出队列的起始位置,此时另外一个进程也是可以同时出队列的,只是要排队修改尾指针
  2. 然后取出数据
  3. 然后更新尾指针,其他进程排队更新尾指针

参考:https://blog.csdn.net/gengzhikui1992/article/details/108202876

(精简理解)DPDK的无锁环形队列Ring相关推荐

  1. dpdk的无锁环形队列Ring

    1. DPDK Ring简介 dpdk实现了一个无锁环形队列Ring,可用于在dpdk不同的应用程序之间进行通信. Ring支持的效果: 先进先出 最大大小是固定的,指针存储在表中 无锁实现 多消费者 ...

  2. 无锁环形队列的几种高效实现

    1.环形队列是什么 队列是一种常用的数据结构,这种结构保证了数据是按照"先进先出"的原则进行操作的,即最先进去的元素也是最先出来的元素.环形队列是一种特殊的队列结构,保证了元素也是 ...

  3. 理解 Memory barrier(内存屏障)无锁环形队列

    Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的性能.内存乱序访问主要发生在两 ...

  4. 无锁环形缓冲区的详细解释

    由以下博客的分析可以知道,内核的kfifo使用了很多技巧以实现其高效性.比如,通过限定写入的数据不能溢出和内存屏障实现在单线程写单线程读的情况下不使用锁.因为锁是使用在共享资源可能存在冲突的情况下.还 ...

  5. 【共享内存】基于共享内存的无锁消息队列设计

    上交所技术服务 2018-09-05 https://mp.weixin.qq.com/s/RqHsX3NIZ4_BS8O30KWYhQ 目录 一.背景 二.消息队列的应用需求 (一)  通信架构的升 ...

  6. java的“看门狗”锁续期可以用php redis这样实现【php锁续期、分布式锁、无锁请求队列超卖】解决【商家超卖(商品库存控制)、用户超买(秒杀订单控制)】问题。非demo 线上一直在用

    要求与痛点描述 1.不允许使用库存创建队列 因为库存如果是10w难道要创建一个10w长度的队列吗 2.不允许对整个业务过程加锁 可能业务执行时间很长 导致锁粒度太大 影响并发量 3.如果业务时间大于锁 ...

  7. 深入理解高并发技术dpdk无锁队列

    前两周给大家直播分享,并发技术全景(从硬件,操作系统,虚拟机/标准库,编程语言等) 上半场(5个小时):并发/并行技术全景指南 下半场(5个小时):人生的下半场,你准备好了吗 最后我上周还布置了一个作 ...

  8. DPDK无锁队列rte_ring相关代码及示例程序(rte_ring.h,rte_ring.c,main.c,makefile)

    目录 rte_ring.h rte_ring.c main.c makefile 推荐阅读: [共享内存]基于共享内存的无锁消息队列设计:https://rtoax.blog.csdn.net/art ...

  9. 你应该知道的高性能无锁队列Disruptor

    1.何为队列 听到队列相信大家对其并不陌生,在我们现实生活中队列随处可见,去超市结账,你会看见大家都会一排排的站得好好的,等待结账,为什么要站得一排排的,你想象一下大家都没有素质,一窝蜂的上去结账,不 ...

最新文章

  1. angularJs的学习笔记-01(创建项目)
  2. java信息格式化,Java如何格式化包含时间信息的消息?
  3. 使用Callable来获取数组的最大值
  4. 操作系统安装必备基础知识----浅谈电脑系统里的那些UEFI, BIOS, MBR, GPT。
  5. 如何把一个软件嵌入另一个软件_新增一个软件一个游戏
  6. linux驱动之ioctl
  7. HDU-2553-N皇后问题
  8. 汉字统计--统计给定文本文件中汉字的个数。
  9. graphene-django开发实践——登录为例
  10. 从童年回忆到“人人喊打“,好丽友做错了什么?
  11. 基于Echarts实现可视化数据大屏交通类大数据展示页面模板
  12. 崔希凡JavaWeb笔记day28(JavaWeb完毕)(期末,暂停更新)(2016年11月16日12:24:03)
  13. 第三章:SQL——视图操作
  14. postfix连接不上mysql_mysql – Postfix sasl登录失败没有找到机制
  15. 修复 rk3288 android9 的一些问题
  16. 史上最全的Altium Designer 20安装教程
  17. 利用计算机课堂导入的好处,多媒体教学的好处
  18. 没有上下音量键,如何实现fastboot 模式下unlock/lock
  19. 怎样降低EDIUS中声音
  20. mac安装 Docker

热门文章

  1. 一个非知识库的中文分词算法实现
  2. 螺旋探索与自适应混合变异的麻雀搜索-附代码
  3. 《大话数据结构》看书笔记--算法
  4. html5写花,HTML5 盛放的花朵
  5. 大盘点 | 性能最强的目标检测算法
  6. 【CSS】下划线与文字间距,下划线粗细以及下划线颜色的设置
  7. 【腾讯广告】监测链接和API自归因回传接口逻辑
  8. 【C语言每日一练——第1练:字母大小写转换】
  9. D. Alex and Julian
  10. 车载产品Bootloader功能的应用与实现