dpdk学习之多进程simple_mp源代码分析
来源:互联网 发布:梦天堂软件 编辑:程序博客网 时间:2024/06/06 05:51
1.实现思路分析
dpdk提供了进程间共享的方法,需要以下几步来完成。
1.rte_ring需要与rte_mempool配合使用,通过rte_mempool来共享内存。
// 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);
2.首先primary进程创建ring和mempool,secondary进程在primary进程启动后,通过rte_ring_lookup和rte_mempool_lookup来获取ring和mempool的地址。
struct rte_ring *ring = rte_ring_lookup("message_ring");struct rte_mempool *message_pool = rte_mempool_lookup( "message_pool");
3.使用时,rte_mempool_get从mempool中获取一个对象,然后使用rte_ring_enqueue入队列,另一个进程通过rte_ring_dequeue来出队列,使用完成后需要rte_mempool_put将对象放回mempool。
2.一步步进行代码分析
main函数,将在primary进程创建两个ring队列
- 发送队列 PRI_2_SEC
- 接受队列 SEC_2_PRI
对于secondary进程,查找发送和接受队列,顺序跟primary相反:
- 发送队列 SEC_2_PRI
- 接受队列 PRI_2_SEC
当在primary进程执行send hello1时,使用的是dpdk自带的cmdline库
struct cmdline *cl = cmdline_stdin_new(simple_mp_ctx, "\nsimple_mp > "); if (cl == NULL) rte_exit(EXIT_FAILURE, "Cannot create cmdline instance\n"); cmdline_interact(cl); cmdline_stdin_exit(cl);
定位到simple_mp_ctx结构体中
cmdline_parse_ctx_t simple_mp_ctx[] = { (cmdline_parse_inst_t *)&cmd_send, (cmdline_parse_inst_t *)&cmd_quit, (cmdline_parse_inst_t *)&cmd_help, NULL,};
cmd_send对应”send”命令的结构体指针
cmd_quit对应”quit”命令的结构体指针
cmd_help对应”help”命令的结构体指针
点击进入cmd_send
cmdline_parse_inst_t cmd_send = { .f = cmd_send_parsed, /* function to call */ .data = NULL, /* 2nd arg of func */ .help_str = "send a string to another process", .tokens = { /* token list, NULL terminated */ (void *)&cmd_send_action, (void *)&cmd_send_message, NULL, },};
一切都清楚了,当在控制台输出send xxx命令时,会调用cmd_send_parsed函数进行逻辑处理
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); //ring入队操作 if (rte_ring_enqueue(send_ring, msg) < 0) { printf("Failed to send message - message discarded\n"); //将对象归还给内存池 rte_mempool_put(message_pool, msg); }}
对于primary进程,
/* call lcore_recv() on every slave lcore */ RTE_LCORE_FOREACH_SLAVE(lcore_id) { rte_eal_remote_launch(lcore_recv, NULL, lcore_id); }
在每个slave核心上执行lcore_recv函数调用。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; //ring 出队操作 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;}
3.
至此,我们总结下,进程之间通过ring来共享数据内容,数据内容是存储在从内存池申请的对象上的。
流程如下:
从内存池申请对象->入队ring->将对象归还给内存池
参考资料:
dpdk的使用说明,请参考
http://blog.csdn.net/njnu_mjn/article/details/52474300
- dpdk学习之多进程simple_mp源代码分析
- dpdk之多进程client_server_mp源代码分析
- dpdk多进程示例解读(examples/multi_process/simple_mp)
- dpdk多进程示例解读(examples/multi_process/simple_mp)
- dpdk学习之ip_pipeline源代码分析
- DPDK学习笔记<4>源代码分析(1)
- Webkit之多进程分析
- Python学习之多进程实例
- Webbench源码分析之多进程(三)
- dpdk学习
- dpdk中文-DPDK学习路线图
- dpdk学习之一--初识dpdk
- Python学习之多进程并发爬虫
- dpdk helloworld代码分析
- DPDK代码内存分析
- dpdk helloworld代码分析
- dpdk 代码分析一
- DPDK分析--深入浅出
- freopen函数用法
- Codeforces816B Karen and Coffee
- 使用Theme设置页面切换动画
- 编程小技巧
- android
- dpdk学习之多进程simple_mp源代码分析
- VMware虚拟机Mac OS X如何调整扩展硬盘大小
- 面试题 49: 把字符串转换为整数
- Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据
- 通过编排管理 Docker 容器
- asp 时间截取
- dede栏目添加自定义字段方法
- 如何利用远程导入sql脚本到plsql中
- php框架学习---yii2高级版安装