dpdk无锁队列总结

免责声明:亲爱的网友,虽然我已尽力去还原本文所讲内容的真实情况,但囿于水平不够,以下内容可能全是错的,不过还是希望对你有所启发。

最近被问起一个问题:dpdk无锁队列是怎么实现的?如何能支持多消费者、多生产者?CAS内部的实现原理是什么?

这几个问题彼此关联,层层递进。想要回答清楚,还真不容易。看了一些资料后,说说我对这几个问题的理解。

1、不管是多生产者写入,还是多消费者读取,在dpdk的实现中,都会经过以下三个步骤:

  • 先偏移头指针,说白了就是抢位置,这步主要是为了应对多生产者和多消费者的情况
  • 抢到位置后写入数据或者读取数据
  • 写入或读取完毕后,更新尾指针,让消费者可以消费刚写入的数据,或者让生产者可以写入刚消费过的空间

2、不管是入队列,还是出队列,都是抢先改变头节点的位置,

假设是入队列,则

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

假设是出队列,则

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

3、CAS: 是一个原子操作,由cpu的指令集提供该功能,它需要处理器锁住它的指令流水线来保证原子性。


实现上的考虑:

        为了实现多生产者同时入队列,或多消费者同时出队列,需要为队列维护好以下四个变量:prod_head(生产者头指针)、prod_tail(生产者尾指针)、cons_head(消费者头指针)、cons_tail(消费者尾指针),前两个用于多生产者入队列,后两个用于多消费者出队列。

        维护的基本流程是:
        1)抢占式更新 prod_head(或 cons_head),抢占通过 CAS 指令完成,抢占失败的线程通过 while 循环再次尝试抢占
        2)入队列(或出队列),也即数据拷贝
        3)按抢占成功的顺序依次排队更新 prod_tail(或 cons_tail)

        从一个较长的时间线来看,在多生产者入队列开始前,prod_head 是等于 prod_tail 的,在多生产者入队列结束后,prod_head 还是等于 prod_tail 的,这是一个非常重要的约束。在多生产者入队列中,prod_head 和 prod_tail 会出现不相等的情况,这是一个从相等到不相等,再到相等的动态变化过程。在这个过程中,某个线程只有先成功更新 prod_head,才能安全的入队列,入队列结束后,要依次更新 prod_tail,最后的结果就是 prod_head 和 prod_tail 又重新相等。

参考资料

1、【DPDK】【ring】从DPDK的ring来看x86无锁队列的实现 - Jungle1996 - 博客园

2、DPDK 无锁队列Ring Library原理(学习笔记) - 一觉醒来写程序 - 博客园

3、深入理解dpdk rte_ring无锁队列_NTF的博客-CSDN博客_rte_ring_create

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值