用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

### DPDK多进程源码分析 DPDK(Data Plane Development Kit)是一个高性能的数据平面开发工具包,主要用于加速网络应用中的数据包处理。其多进程支持允许多个独立的DPDK进程协同工作以完成特定的任务[^2]。 #### EAL初始化过程 在DPDK中,多进程的支持主要依赖于EAL(Environment Abstraction Layer)。当启动一个多进程程序时,EAL会负责初始化共享内存区域以及同步机制。这些资源对于不同进程之间的通信至关重要。具体来说,在`rte_eal_init()`函数内部实现了对共享内存段的创建和映射操作。 ```c int rte_eal_init(int argc, char **argv); ``` 该函数不仅解析命令行参数还完成了如下几项重要任务: - 设置全局变量`internal_config->process_type`表示当前运行的是主进程还是次级进程。 - 如果检测到已有其他实例存在,则尝试连接已有的共享内存池;否则新建一个新池子供后续加入者使用。 #### 进程间同步资源共享 为了实现高效而安全的跨进程访问控制,DPDK引入了几种不同的锁原语用于保护临界区代码片段免受竞争条件影响: 1. 自旋锁(`rte_spinlock_t`):适用于短时间锁定场景下减少上下文切换开销; 2. 互斥量(`pthread_mutex_t`)封装版本——即所谓的公平性更好的读写锁方案之一; 3. 原子计数器类APIs如`rte_atomic*_*()`系列宏定义提供了细粒度级别的并发管理能力[^3]。 以下是关于如何利用上述提到的技术构建实际应用程序的一个简单例子展示: ```c #include <rte_common.h> #include <rte_lcore.h> #include <rte_ring.h> struct my_shared_data { struct rte_ring *ring; }; /* Assume this function is called by secondary process */ void init_secondary(struct my_shared_data *data){ data->ring = rte_ring_lookup("my_rings"); } // Primary Process Code Snippet... if (rte_eal_process_type() == RTE_PROC_PRIMARY) { struct my_shared_data pdata; pdata.ring = rte_ring_create("my_rings", 1024, SOCKET_ID_ANY,RING_F_SP_ENQ|RING_F_SC_DEQ); } ``` 通过以上示范可以看出,无论是初级还是辅助角色都能轻松获取预先分配好的环形缓冲队列对象来进行消息传递等活动。 #### 总结 综上所述,DPDK多进程特性极大地增强了系统的灵活性和可扩展性。通过对底层基础设施的有效管理和合理设计接口协议,使得开发者可以更加专注于业务逻辑本身而不必担心复杂的线程调度或者分布式计算带来的额外负担。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值