dpdk多进程示例解读(examples/multi_process/simple_mp)
来源:互联网 发布:淘宝200多的智能机 编辑:程序博客网 时间:2024/06/05 18:06
原文,请到作者原文发表评论。
程序功能
进程之间的master和slave线程互发字串
运行
启动primary和secondary进程
先启动primary进程,-l参数指定使用的逻辑核为core0和core1,–proc-type参数可以省略,默认第一个进程是primary进程,也可以指定值auto,表示自动检测进程的类型
simple_mp -l 0,1 --proc-type primary
程序启动会有大量的日志,初始化结束后,将进入程序命令行界面:
EAL: Detected lcore 0 as core 0 on socket 0EAL: Detected lcore 1 as core 1 on socket 0EAL: Detected lcore 2 as core 2 on socket 0...EAL: Master lcore 0 is ready (tid=c1f1e900;cpuset=[0])...Starting core 1simple_mp >
secondary进程需要在primary进程之后启动,–proc-type参数必须指定(因为不指定该参数,将默认为primary进程,程序将初始化失败,因为已经存在了primary进程),值可以为secondary或auto:
simple_mp -l 0,1 --proc-type secondary
secondary进程启动后,同样进入simple_mp命令行。
simple_mp功能
simple_mp使用dpdk cmd_line完成命令行功能,启动simple_mp程序后,输入?
可以查看支持的命令:
simple_mp > send [Fixed STRING]: send a string to another process quit [Fixed STRING]: close the application help [Fixed STRING]: show help
也可以输入
help
查看帮助:simple_mp > helpSimple demo example of multi-process in RTEThis is a readline-like interface that can be used tosend commands to the simple app. Commands supported are:- send [string]- help- quit
primary进程发送字串
在primary进程的命令行中,输入:
simple_mp > send hello1
secondary进程将打印:
simple_mp > core 1: Received 'hello1'
在secondary进程执行
send hello2
,primary进程也将打印core 1: Received 'hello2'
分析
收发队列
main函数,将在primary进程创建两个ring队列
- 发送队列 PRI_2_SEC
- 接受队列 SEC_2_PRI
if (rte_eal_process_type() == RTE_PROC_PRIMARY){ send_ring = rte_ring_create(_PRI_2_SEC, ring_size, rte_socket_id(), flags); recv_ring = rte_ring_create(_SEC_2_PRI, ring_size, rte_socket_id(), flags); message_pool = rte_mempool_create(_MSG_POOL, pool_size, string_size, pool_cache, priv_data_sz, NULL, NULL, NULL, NULL, rte_socket_id(), flags);} else { recv_ring = rte_ring_lookup(_PRI_2_SEC); send_ring = rte_ring_lookup(_SEC_2_PRI); message_pool = rte_mempool_lookup(_MSG_POOL);}
对于secondary进程,查找发送和接受队列,顺序跟primary相反:
- 发送队列 SEC_2_PRI
- 接受队列 PRI_2_SEC
当在primary进程执行send hello1
时,cmd_send_parsed函数执行入队PRI_2_SEC逻辑:
/* simple_mp/mp_commands.c */static void cmd_send_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data){ void *msg = NULL; struct cmd_send_result *res = parsed_result; if (rte_mempool_get(message_pool, &msg) < 0) rte_panic("Failed to get message buffer\n"); snprintf((char *)msg, string_size, "%s", res->message); if (rte_ring_enqueue(send_ring, msg) < 0) { printf("Failed to send message - message discarded\n"); rte_mempool_put(message_pool, msg); }}
(primary进程)每个slave core上的线程,在SEC_2_PRI执行出队,master线程通过管道消息通知(rte_eal_remote_launch)每个slave线程执行lcore_recv函数:
static intlcore_recv(__attribute__((unused)) void *arg){ unsigned lcore_id = rte_lcore_id(); printf("Starting core %u\n", lcore_id); while (!quit){ void *msg; if (rte_ring_dequeue(recv_ring, &msg) < 0){ usleep(5); continue; } printf("core %u: Received '%s'\n", lcore_id, (char *)msg); rte_mempool_put(message_pool, msg); } return 0;}
内存管理
ring队列存储的是指针,所以内存需要自己申请。
primary进程创建名为MSG_POOL
的内存池,可以存放1024个元素,每个元素的大小是64字节,逻辑核缓存32个元素。
secondary进程使用primary创建的内存池:
if (rte_eal_process_type() == RTE_PROC_PRIMARY){ message_pool = rte_mempool_create(_MSG_POOL, pool_size, string_size, pool_cache, priv_data_sz, NULL, NULL, NULL, NULL, rte_socket_id(), flags);} else { message_pool = rte_mempool_lookup(_MSG_POOL);}
入队前,先获取内存池的一块内存:
if (rte_mempool_get(message_pool, &msg) < 0) rte_panic("Failed to get message buffer\n");snprintf((char *)msg, string_size, "%s", res->message);if (rte_ring_enqueue(send_ring, msg) < 0) { printf("Failed to send message - message discarded\n"); rte_mempool_put(message_pool, msg);}
出队后归还内存池:
if (rte_ring_dequeue(recv_ring, &msg) < 0){ usleep(5); continue;}printf("core %u: Received '%s'\n", lcore_id, (char *)msg);rte_mempool_put(message_pool, msg);
注意:本进程的slave线程收不到master线程的消息,master线程将消息入队到PRI_2_SEC,而slave从SEC_2_PRI队列读取消息
在线源码
http://dpdk.org/browse/dpdk/tree/examples/multi_process/simple_mp
- dpdk多进程示例解读(examples/multi_process/simple_mp)
- dpdk多进程示例解读(examples/multi_process/simple_mp)
- dpdk学习之多进程simple_mp源代码分析
- 多进程编程 Multi_Process
- DPDK 多进程支持总结
- DPDK-MULTI-PROCESS SUPPORT 多进程支持
- 用DPDK rte_ring实现多进程间通信
- DPDK(一):DPDK安装
- Three.js 教程和示例(Tutorials and Examples)
- Java API 示例搜索引擎(Java API Examples Searcher)
- DPDK(17):网卡多队列技术与RSS功能介绍、DPDK多队列
- 【机器人学】机器人开源项目KDL源码学习:(4)examples中的CMakeList.txt文件解读
- DPDK(六):DPDK整体介绍
- DPDK(14):rte_mbuf
- DPDK学习(rte_eal_init)
- DPDK学习(eal_thread_loop)
- DPDK学习(基础知识)
- dpdk之多进程client_server_mp源代码分析
- 【ARM-Linux开发】linux下Eclipse进行C编程时动态链接库的生成和使用
- HTML 2 标签
- APP 签名 与 APK 优化
- 学习历程(四)微信天气预报小demo
- 百词斩
- dpdk多进程示例解读(examples/multi_process/simple_mp)
- 虚拟机中的ubuntu怎么设置1920X1080分辨率
- Python包管理:pip、easy_install、eggs和wheel
- Linux内核中的fastcall和asmlinkage宏
- 斐波那契数列和青蛙跳问题
- 【放苹果(题解)】
- JAVA中关于List集合和map集合之间的继承关系
- C#语法小知识(十八)const与readonly
- 文件描述符fd和文件指针fp之间的相互转换