使用mmap()映射多个进程以共享内存区域

问题描述 投票:2回答:2

对于一个项目,我必须使用:

void *ptr = mmap(NULL, N, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);

其中N是要从OS请求的RAM字节数。

执行此语句时,ptr指向什么?它是否指向进程之间共享内存的开始?另外,如果说我要存储1,000个int指针,是否需要N = 1000 * sizeof(int *);

并且假设我是对的,那么我可以存储某些东西的内存中的第二个位置在哪里?是在32位系统上ptr + 1是4个字节,是ptr + 4还是int *

谢谢,谢谢。

c pointers memory mmap
2个回答
1
投票

由于mmap未在标准C中定义,我假设您正在使用此:http://linux.die.net/man/2/mmap

返回值是指向内存的指针:

成功时,mmap()返回一个指向映射区域的指针。出现错误时,返回值MAP_FAILED(即(void *)-1),并设置了errno适当地。成功时,munmap()返回0,失败时返回-1,并且设置了errno(可能设置为EINVAL)。

您正在正确计算N。

但是,使用void*指针使用加法可能会遇到问题,因此将指针转换为int*进行加法。

int* p = ptr;
int* nextP = p + 1;

0
投票
void *ptr = mmap(
    NULL, N,
    PROT_READ|PROT_WRITE,
    MAP_SHARED|MAP_ANONYMOUS,
    0, 0);

其中N是要从操作系统请求的RAM字节数。

这里是您必须]的一个重要约束:N必须是系统页面大小的整数倍(或者,如果映射大页面,则是大页面大小的整数倍)。通常为4096字节,但实际值由sysconf(PAGESIZE)报告。

执行此语句时,ptr指向什么?

创建此特定映射的地址空间部分的开始。使用非匿名映射,您可以将同一内存多次映射到不同的地址(这是实现透明环形缓冲区的巧妙技巧)。

是否指向进程之间共享内存的开始?

在这一点上,它只是指向some

内存。 <fork(或带有正确标志的clone)之后共享;这已经是进程共享的内存,但是您可能还希望将execve转换为其他可执行文件。
此外,如果在这个存储空间中说我想存储1,000个int指针,我是否需要N = 1000 * sizeof(int *);?

嗯,从技术上讲,您需要拥有n * sysconf(PAGESIZE) == N >= 1000 * sizeof(int*);但是,为什么要共享int

pointers

?除非您将那些pointers指向(另一个)共享内存区域,否则在使用这些指针的每个进程中该地址都位于相同的地址,否则共享pointers几乎是没有用的。当然,在fork之后,进程的地址空间是相同的,但是execve将取消映射所有先前的映射,并且您必须将非匿名mmapMAP_FIXED结合使用,并使用通过获得的文件描述符,例如memfd_create,并使用mmap的第一个参数精确地将其映射到(可能会失败,或者过度映射以前存在的映射)。您可以合理共享的是

offsets

bulk data。哦,只是为了消除任何混乱:将指针放在共享内存区域中不会自动共享其指向的内存。

并且假设我是对的,那么内存中的第二位在哪里我可以储存东西吗?是int是ptr +1还是ptr + 4*在32位系统上是4个字节吗?

这只是普通的内存,您可以使用,就像它是用malloc分配的一样。将指针强制转换为您认为合适的任何类型,然后照常使用它。

© www.soinside.com 2019 - 2024. All rights reserved.