用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

好的,我来为您介绍一下DPDKRTE_FLOW_ACTION_TYPE_COUNT action的用法。 RTE_FLOW_ACTION_TYPE_COUNT是DPDK中用于流量控制的一种动作类型,它可以将匹配的流量复制到一个或多个端口或队列中。这种动作通常用于流量监控、镜像或分流等场景。 以下是RTE_FLOW_ACTION_TYPE_COUNT action的主要用法: 1. 基本概念: - COUNT动作可以将匹配的流量复制到多个目标端口或队列。 - 原始流量仍会被正常处理和转发。 - COPY动作不会修改原始数据包。 2. 主要参数: - actions: 包含一个或多个动作的数组。 - nb_actions: 动作数组中的动作数量。 3. 动作类型: - PORT: 将数据包复制到指定端口。 - QUEUE: 将数据包复制到指定队列。 4. 使用示例: ```c struct rte_flow_action_copy copy_actions[] = { { .type = RTE_FLOW_ACTION_TYPE_PORT, .conf = &port_conf, }, { .type = RTE_FLOW_ACTION_TYPE_QUEUE, .conf = &queue_conf, }, }; struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_COPY, .conf = copy_actions, }, // 其他动作... }; struct rte_flow_attr attr = {0}; struct rte_flow *flow = rte_flow_create(port_id, &attr, actions, NULL, NULL); ``` 5. 注意事项: - COPY动作通常需要与其他动作组合使用。 - 过多的COPY动作可能会影响性能。 - 某些硬件可能对COPY动作的实现方式有所不同。 6. 优点: - 灵活: 可以将流量复制到多个目标。 - 性能高: 硬件加速,不会显著影响原始流量处理。 - 保持原始数据完整性: 不会修改原始数据包。 使用RTE_FLOW_ACTION_TYPE_COUNT action可以有效地实现复杂的多流处理需求,提高流量监控和分析的效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值