DPDK中文-DPDK的ring

bestboyxie 励志做一名能帮助到他人的程序员,如果你觉得这篇文章对你有帮助,麻烦你 点赞
DPDK的ring是一个线程安全的队列 支持单生产者单消费模型 同时也支持多生产者多消费者模型
一、单生产者单消费者模型 二、多生产者对消费者模型
多生产者多消费者应该至少是由原子变量或者锁来完成的,而单生产者单消费者则可以做到完全无锁,效率感觉单生产者单消费应该是最高的;不然这个单生产者单消费者就没有存在的必要了;、 效率:单生产者单消费者最高 本文章的内容是dpdk的example代码梳理出来的;
DPDK的ring特点 1。dpdk来保证高效; 2。多线程多进程都可以用; 3。常用来跨进程、线程间通信用; 所谓队列其实就是fifo。先进先出; dpdk的ring入队列的是 一个指针,配套使用dpdk的共享内存,很容易实现进程间低消耗的通讯;
一般流程 创建ring——》入队列-》出队列 一、创建ring

struct rte_ring * rte_ring_create(const char *name, unsigned count, int socket_id,unsigned flags)



第一个参数:ring的名字,dpdk 的所有内存结构都可以通过名字来标记; 第二个参数:ring的个数 count 貌似这个count记得要设置为2的N次方。不然会失败; 第三个参数:socketid核的id。一般如果创建自己用,使用rte_socket_id()函数就OK了。如果是跨核访问使用对应socketid就好了。(这个参数在多CPU平台上有用); 第四个参数:flag。主要指单生产者 (RING_F_SP_ENQ )单消费(RING_F_SC_DEQ),如果是0就是多生产者多消费;
例子
struct rte_ring * ring_p = rte_ring_create("myring",1024,0,RING_F_SP_ENQ |RING_F_SC_DEQ)


二、查找ring 如果ring是两个进程共享的,这个时候非创建者只需要使用查找ring的函数查找到ring就可以使用了;
struct rte_ring * rte_ring_lookup(const char *name)


例子:
struct rte_ring * ring_p = rte_ring_lookup("myring")



三、入/出队列 入/出队列有两种。一种是单个单个的入,一种是一次性入一群;
int rte_ring_enqueue(struct rte_ring *ring,void *data)


<<------>>
int rte_ring_dequeue(struct rte_ring *ring,void **data)


int rte_ring_enqueue_bulk(struct rte_ring *ring,void **data,int count)


<<------>>
int rte_ring_dequeue_bulk(struct rte_ring *ring,void **data,int count)


示例使用 rte_ring_enqueue /rte_ring_dequeue 返回值为0成功,否则失败; 进程1 struct rte_mbuf *mbuf=xxxx; rte_ring_enqueue(ringp,mbuf); 进程2 struct rte_mbuf *mbuf=NULL; rte_ring_dequeue(ringp,&mbuf);
rte_ring_enqueue_bulk 返回值为实际入队列的个数 rte_ring_dequeue_bulk返回值为0,则全部成功。否则一个都不会成功 进程1
struct rte_mbuf *mbuf[100]; ..... int count = rte_ring_enqueue_bulk(ringp,(void **)mbuf,100); if(count != 100){ for(; count<100; count++){ rte_mbuf_free(mbuf[count]); } }



进程2
int count= rte_ring_count(ringp); struct rte_mbuf *mbuf[100]; if(rte_ring_dequeue_bulk(ringp,(void **)mbuf,100) == 0){ //do something }


四、删除ring; rte_ring_free(ringp); 五、ring状态获取 查看已经使用的count数目 rte_ring_count() 查看空闲的count数据 rte_ring_free_count() 一键判断空/满 rte_ring_empty/rte_ring_full
所有的API都在 rte_ring.h中,上下文都比较详细 参考代码可以查看 examples\multi_process 下面的代码即可
高级用法。 dpdk ring 设置水位线。用于队尾丢弃策略的控制;
如果觉得好, 请下面顶




    推荐阅读