用DPDK rte_ring实现多进程间通信

F-Stack是多进程架构,去除了进程间资源共享来达到更高的性能,但还是有部分控制信息需要在进程间同步,使用rte_ring让多个进程间的通信变得十分简单。

rte_ring在F-Stack中主要用于:

1.各个进程间ARP包的广播
2.KNI的转发
3.与工具(sysctl等)进行通信。

rte_ring是一个用CAS实现的无锁FIFO环形队列,支持多消费者/生产者同时出入队列,常用于多线程/多进程之间的通信。具体原理可以查看DPDK官方文档或者阅读源码,本文主要是介绍如何使用rte_ring来进行多进程间通信。

rte_ring需要与rte_mempool配合使用,通过rte_mempool来共享内存。

首先primary进程创建ring和mempool,secondary进程在primary进程启动后,通过rte_ring_lookup和rte_mempool_lookup来获取ring和mempool的地址。

primary:

// flags:标识是单消费者/生产者或者多消费者/生产者
struct rte_ring *ring = rte_ring_create("message_ring",
        ring_size, rte_socket_id(), flags);
struct rte_mempool *message_pool = rte_mempool_create(
        "message_pool", pool_size,
        string_size, pool_cache, 0,
        NULL, NULL, NULL, NULL,
        rte_socket_id(), flags);

secondary:

struct rte_ring *ring = rte_ring_lookup("message_ring");
struct rte_mempool *message_pool = rte_mempool_lookup(
        "message_pool");

使用时,rte_mempool_get从mempool中获取一个对象,然后使用rte_ring_enqueue入队列,另一个进程通过rte_ring_dequeue来出队列,使用完成后需要rte_mempool_put将对象放回mempool。

sender:

void *msg = NULL;

if (rte_mempool_get(message_pool, &msg) < 0)
    pannic();

snprintf((char *)msg, string_size, "%s", "helloworld");
if (rte_ring_enqueue(ring, msg) < 0) {
    rte_mempool_put(message_pool, msg);
}

receiver:

while (!quit){
    void *msg;

    if (rte_ring_dequeue(recv_ring, &msg) < 0){
        usleep(5);
        continue;
    }

    printf("Received: '%s'\n", (char *)msg);

    rte_mempool_put(message_pool, msg);
}

实际代码可以参考dpdk example/multi_process/simple_mp 或者F-Stack lib/ff_dpdk_if.ctools/ipc,非常简单易用。

原文链接:https://www.qcloud.com/community/article/542268

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: rte_ring_sc_dequeue_bulk是DPDK中的一个函数,用于从单个生产者,单个消费者环形队列中批量出队一组元素。"sc"代表"single consumer",表示只有一个消费者在访问该队列。该函数的原型如下: ``` uint32_t rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table, uint32_t n) ``` 其中,参数r是指向环形队列的指针,obj_table是一个指向指针数组的指针,用于存储出队的元素,n表示要出队的元素数量。 函数的返回值是实际出队的元素数量,可能小于请求的数量n。如果队列为空,则返回0。该函数是线程安全的,可以在多个线程之间并发调用。 ### 回答2: rte_ring_sc_dequeue_bulk是DPDK(Data Plane Development Kit)库中的一个函数,用于从指定的环形缓冲区中以"单一消费者"的方式批量取出元素。 该函数的作用是从环形缓冲区中按照先入先出原则取出一定数量(批量)的元素,并将它们存储到用户提供的缓冲区中。在单一消费者的情况下,该函数可以提供更高的性能。 该函数的原型为: ```c uint32_t rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table, uint32_t n, const unsigned int *restrict offset) ``` 参数说明: - r:指向目标环形缓冲区的指针。 - obj_table:指向用户提供的缓冲区指针的指针,用于存储从环形缓冲区中取出的元素。 - n:用户期望从环形缓冲区中取出的元素数量。 - offset:用户提供的存储偏移量的数组指针,用于存储从缓冲区中每个元素的偏移量值。 该函数的返回值为实际取出的元素数量。 使用rte_ring_sc_dequeue_bulk函数可以实现高效地从环形缓冲区中取出一定数量的元素,可以提高数据处理的效率。需要注意的是,在使用该函数之前,必须先创建好环形缓冲区,并确保环形缓冲区中有足够的元素可供取出。 ### 回答3: rte_ring_sc_dequeue_bulk是一个函数,用于从单生产者、单消费者环形缓冲区中以原子操作的方式批量出队元素。 它的功能是从环形缓冲区中连续出队指定数量的元素,并返回实际出队的元素数量。它是无锁的,采用强制屏障以确保原子性。 使用rte_ring_sc_dequeue_bulk函数时,需要传入一个指向环形缓冲区的指针,以及一个指向存储出队元素的数组的指针,以及期望出队的元素数量。 函数会按先进先出的顺序出队元素,并将其存储到数组中。如果实际出队的元素数量小于期望的数量,则代表环形缓冲区中的元素数量不足,所有剩余的元素都将被出队。 rte_ring_sc_dequeue_bulk函数会根据环形缓冲区的状态,使用原子操作进行出队操作,避免多个线程同时修改环形缓冲区造成冲突。在出队操作的同时,它使用强制屏障来确保原子性,确保出队操作的结果对其他线程可见。 总之,rte_ring_sc_dequeue_bulk函数是一个高效、无锁的函数,用于在单生产者、单消费者环形缓冲区中以原子操作的方式批量出队元素。它可以帮助提高多线程程序的性能,并保证线程安全性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值