hello_world涉及的知识点
- 这个示例实现的功能是什么?
主要就是检查eal环境抽象初始化是否成功,其中rte_eal_init会根据指定核数创建从线程,以及对应的线程loop函数。
2 .DPDK主从线程如何通信?
利用进程通信机制的pipe管道,本质是一个内核维护的环形缓冲队列,大小为get_free_page返回的一页内存。
管道为半双工的,因此,只能固定一方写一方读,从管道读取过的数据就无法再次被读了。
让我们看看linux-0.11是如何实现pipe的:
int pipe(int pipefd[2]);
每个进程最多可以打开文件数为NR_OPEN,首先遍历该进程未使用的文件句柄,找到可用的两个句柄,那么fd[0]和fd[1]返回的就是filp数组的下标。
接着遍历全局可用的文件描述符,找到可用的两个,接着在全局inode表中找到一个可用的inode节点,然后将两个文件描述符的inode指针都指向它。
通过inode获取硬盘逻辑缓存区,具体由super_block和inode idx获取缓存区buffer,然后将inode信息写入。
inode->isize = 一页内存的首地址,即后续环形管道的首地址。
让我们利用pipe写一个简单的进程通信示例:
//父进程给子进程发送msg
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
char buf[1024];
int fd[2];
pipe(fd);
char *p = "test for pipe\n";
pid = fork();
if (pid < 0) {
printf("fork err\n", buf);
} else if (pid == 0) {
close(fd[1]);
int len = read(fd[0], buf, sizeof(buf));
printf("we get father msg:%s\n", buf);
close(fd[0]);
} else {
close(fd[0]);
write(fd[1], p, strlen(p));
wait(NULL);
close(fd[1]);
}
return 0;
}
无情gdb
rte_eal_init后会启动若干个线程,个数与硬件核数或配置核数有关,每个子线程都有各自的与主线程通信的pipe管道,这个管道的作用是:当主线程想要分配某一个函数让子线程执行时,主线程会通过pipe发送消息(1个字节,内容无所谓),子线程读取到这个消息后会回送给主线程一个消息,然后子进程便开始执行主线程赋值的函数(lcore_hello),而主线程收到子线程的回信后,就可以去给其他的线程分配函数了。
至此,各个子线程死循环执行线程函数eal_thread_loop,不断执行主线程分配的函数。
rte_eal_remote_launch中,主线程为指定的子线程赋值其功能函数:
static int
lcore_hello(__rte_unused void *arg)
{
unsigned lcore_id;
lcore_id = rte_lcore_id();
printf("hello from core %u\n", lcore_id);
return 0;
}
lcore_config[worker_id].f = lcore_hello;
lcore_config[worker_id].arg = arg;
然后主线程会往该子线程的pipe中写一个1字节的内容,接着会while等待子线程是否分配好了执行函数,具体的执行过程以及何时结束主线程不关心。
eal_thread_loop中,子线程循环读取pipe,当读到一个字节的时候,这意味着主线程已经分配给我了一个函数任务,那么我写入pipe一个字节告诉主线程我知道了,这就开始干活,并把自己的状态置为RUNNING,函数执行完毕后再置为FINISHED
/* call the function and store the return value */
fct_arg = lcore_config[lcore_id].arg;
ret = lcore_config[lcore_id].f(fct_arg);
lcore_config[lcore_id].ret = ret;
下面是我通过set scheduler-locking on捕获的一次完整的主从线程通信:
Reference
(27条消息) dpdk-16.04 eal lcore 多线程机制分析_龙瑜的博客-CSDN博客
(27条消息) dpdk之CPU绑定_liyu123__的博客-CSDN博客_dpdk绑核
(27条消息) dpdk_lcore_note_DPDK_lcore_学习笔记_Andrew Yang's Note-CSDN博客
(1条消息) linux管道pipe详解_oguro的博客-CSDN博客_管道
(1条消息) 理解inode_zhanshenyn的专栏-CSDN博客