用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,非常简单易用。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

MySQL 之 SQL 优化实战记录

N个机台将业务数据发送至服务器,服务器程序将数据入库至MySQL数据库。服务器中的javaweb程序将数据展示到网页上供用户查看。

511
来自专栏MYSQL轻松学

你了解的max_allowed_packet

Error updating database. Cause: com.mysql.jdbc.MysqlDataTruncation: Data trun...

3537
来自专栏CodingToDie

事务

在日常的工作和开发中,接触最多的便是与数据库打交道,无论你使用什么框架进行开发都绕不开事务的管理. 在Java开发中你可能会接触很多ORM框架,无论是Hiber...

752
来自专栏Spark学习技巧

Kafka源码系列之如何删除topic

本文依然是以kafka0.8.2.2为例讲解 一,如何删除一个topic 删除一个topic有两个关键点: 1,配置删除参数 delete.topic.enab...

3389
来自专栏菩提树下的杨过

mybatis 3.x 缓存Cache的使用

mybatis 3.x 已经支持cache功能了,使用很简单,在mappper的xml文件里添加以下节点: 1 <mapper namespace="com....

19910
来自专栏性能与架构

Redis 优化执行命令的延时

Redis 是单线程的,客户端的命令请求在server中会被排队,按照顺序处理,如果队列长,命令执行结果的响应时间便会长 ? 如果客户端想要快点得到执行结果,可...

4676
来自专栏蓝天

redis for lack of backlog

版本: redis-3.2.9 部署: 5台64G内存的物理机,每台机器启动2个redis进程组成5主5备集群,每台机器1个主1个备,并且错开互备...

935
来自专栏Kirito的技术分享

深入理解 RPC 之集群篇

上一篇文章分析了服务的注册与发现,这一篇文章着重分析下 RPC 框架都会用到的集群的相关知识。 集群(Cluster)本身并不具备太多知识点,在分布式系统中,...

3269
来自专栏Jackson0714

sys.dm_db_wait_stats

30212
来自专栏Java Edge

读懂Java中的Socket编程

Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一。如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实...

612

扫码关注云+社区