IO uring 在多个无继承关系的进程之间共享io

本文介绍了在项目中使用io-uring实现多个进程共享内存以进行文件读写的过程,包括用户态提供内存、内存大页使用、SQPOLL设置及可能遇到的内存限制和权限问题。
摘要由CSDN通过智能技术生成

最近的project上遇到了需要在多个进程共享一个io-uring,对同一个文件进行读写的需求,这边写一下实现思路和遇到的问题。

实现思路:

首先io-uring的内存空间是内核态和用户态是共享的,接着最新一版io-uring提供了io_uring_queue_init_mem函数,通过这个函数原本由内核分配的内存空间现在可以由用户态程序提供(一个内存大页)。在此基础上,用户态提供的内存是共享的,也就可以实现多个进程之间的共享。

下面直接上代码:

用户态程序首先构建一个共享的内存大页

bs->sh_fd = shmget(1234, SHM_HUGE_2M, IPC_CREAT|SHM_HUGE_2M|SHM_HUGETLB|0666);
if (bs->sh_fd == -1 )
{
     printf("semget  is wrong \n");
}
bs->s_ptr  = shmat(bs->sh_fd, bs->s_ptr, 0);
if (bs->s_ptr  == (void *)-1)
{
                printf("semget  is wrong \n");
}
memset(bs->s_ptr, 0, SHM_HUGE_2M);

这边我使用了系统默认的2M大页,但是感觉会有sqe,和cqe上的限制,返回值显示只用了 8K的内存,但是entry的数量最大设置到64。(这块的内核代码没有细看到底问题出在哪,因为64个sqe对我来说也够用了,也许分配个1G的大页也许会解决)

bs->p->flags |= IORING_SETUP_SQPOLL | IORING_SETUP_NO_MMAP;
bs->p->resv[0] = bs->p->resv[1] = bs->p->resv[2] = 0;
bs->p->sq_thread_idle = 0xfffffffe;
ret = io_uring_queue_init_mem(64, bs->ring, bs->p, bs->s_ptr, SHM_HUGE_2M);
printf("ret is %u\n",ret);

if (ret== -ENOMEM) {
    printf("io_uring share memory mmap init error. no enought memory\n");
}  
if (ret == -EPERM && geteuid()) {
    fprintf(stdout, "SQPOLL skipped for regular user\n");
    goto err_no_bs_opts;
}

另外一个进程,在打开共享大页时需要使用和主进程使用相同的地址,这是因为struct io_uring这个结构体里的指针都是按照偏移量固定好的,如果shmget使用系统自动分配的地址,会导致获得到的结构体里的指针不在当前进程的内存空间中,造成segement fault。

	trace_fd =  shmget((key_t)1234, size, 0666);
	if (trace_fd == -1)
    {
        printf("shmget error\n");
    }
	buf = shmat(trace_fd, addr1, 0);
	if (buf == (void *)-1)
	{
		printf("shmat error\n");
	}

后面将buf转化为struct io_uring*,就可以愉快的使用io-uring了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值