进程间通信有很多方式,如果两个进程是在同一台机器上运行的,效率比较高的通信方式就是共享内存。关于共享内存的实现方式,双方可以通过mmap方式去映射到相同的内存上进而实现内存共享。
DPDK实现的ring也可以帮助我们方便的实现高效率的进程间通信。具体方法如下。
1.rte_ring需要与rte_mempool配合使用,通过rte_mempool来共享内存。
2.primary进程通过rte_ring_create和rte_mempool_create分别创建ring和mempool。
3.secondary进程在primary进程启动后执行,通过rte_ring_lookup和rte_mempool_lookup来获取ring和mempool的地址。
通过上面三个步骤,我们就可以简单的实现一个基于dpdk ring的进程间通信demo
primary进程代码:
//创建一个ring,secondary程序中会通过ring name获取到这个ring
struct rte_ring *ring = rte_ring_create("message_ring", ring_size, rte_socket_id(), flags);
//创建message_pool,secondary程序中会通过pool name获取到这个pool
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);
void *msg = NULL;
//从创建的message_pool中获取一个元素。在dpdk收发包逻辑中,这个msg是rte_mbuf的结构,在这里我们可以根据自己的需要定义不同的结构
if (rte_mempool_get(message_pool, &msg) < 0)
return -1;
//测试,给msg赋值
snprintf((char *)msg, string_size, "%s", "helloworld");
//将msg入队
if (rte_ring_enqueue(ring, msg) < 0)
{
//失败处理,如果入队失败,则把元素放回到pool中。如果成功,这个操作将由secondary进程进行
rte_mempool_put(message_pool, msg);
}
secondary代码:
//根据primary进程中指定的name获取ring和pool的地址
struct rte_ring *ring = rte_ring_lookup("message_ring");
struct rte_mempool *message_pool = rte_mempool_lookup("message_pool");
void *msg;
while(1)
{
//从ring中获取元素
if (rte_ring_dequeue(recv_ring, &msg) < 0)
{
//some handles
continue;
}
printf("Received: '%s'\n", (char *)msg);
//将元素放回到poll中。如果元素出队失败,这个操作将有primary进程执行
rte_mempool_put(message_pool, msg);
}