文章目录
简介
Linux内核无锁环形缓冲(kfifo):
1、单生产、单消费:通过读、写指针,生产、消费不会相互影响,无锁;
2、多生产或者多消费:多个生产之间需要添加互斥保护机制:自旋锁,多消费同理;
3、FIFO;
4、环形:当一个元素pop掉之后,无需移动其他元素位置,减少元素拷贝。
rte_ring:
1、基于Linux内核无锁环形缓冲原理;
2、多生产或者多消费:CAS;
单生产者
单生产者push第一步
1、将生产者的头索引rte->prod_head交给临时变量temp_prod_head;
2、将temp_prod_next偏移下一个或者多个对象(push的个数,以2个为例)的位置;
3、如果在这rte_ring中没有足够的空间capacity,将返回一个错误。
单生产者push第二步
修改rte->prod_head去指向temp_prod_next指向的位置。节点(obj4、obj5)内嵌到ring。
单生产者push第三步
rte->prod_tail修改为temp_prod_next指向的位置,push完毕。
多生产者
多生产者push第一步
1、两个核上,将生产者的头索引rte->prod_head交给临时变量temp_prod_head ;
2、将temp_prod_next指向表的下一个或者多个对象(push的个数,以每个核1个为例) ;
3、如果在这环形缓冲区没有足够的空间capacity,将返回一个错误。
多生产者push第二步
1、core1上CAS成功, rte->prod_head 指向了core1上temp_prod_next1的位置;
2、core2上由于temp_prod_head2不等于rte->prod_head,CAS失败。
3、core2上更新temp_prod_head2为rte->prod_head, temp_prod_next2偏移为下一个或者多个对象。
多生产者push第三步
1、core1上节点obj4内嵌成功;
2、core2上CAS成功, rte->prod_head 指向core2上temp_prod_next2的位置;
3、core2上节点obj5内嵌成功。
多生产者push第四步
1、现在每一个core要更新prod_tail。由于rte->prod_tail == temp_prod_head1 , rte->prod_tail为temp_prod_next1指向的位置;
2、在core2上等待core1的操作完毕
多生产者push第五步
在core2上,当rte->prod_tail == temp_prod_head2,更新将rte->prod_tail指向temp_prod_next2,push完毕
总结
1、消费者实现原理同生产者
2、操作步骤:
2.1 更新rte->prod_head;
2.2 内嵌节点;
2.3 更新rte->prod_tail。
3、多生产或者多消费需要CAS,性能劣与单生产单消费,接口调用时当明确single时需要置single标记。