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

时间:2014-10-04 22:06:14

标签: c pointers memory mmap

对于我必须要做的项目,我必须使用:

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 *);

假设我是正确的,记忆中第二个位置可以存储在哪里?是ptr + 1还是ptr + 4,因为int *在32位系统上是4个字节?

谢谢,我很感激。

2 个答案:

答案 0 :(得分:1)

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

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

  

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

您正在正确计算N.

但是,使用void *指针添加可能会有问题,所以将指针转换为int *以进行添加。

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

答案 1 :(得分:0)

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

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

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

  

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

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

  

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

在这一点上,它只是指向一些内存。到目前为止,还没有任何分享。但是,该映射将在fork(或带有正确标志的clone)之后共享;这已经是进程共享内存了,但是您可能还想execve进入另一个可执行文件。

  

此外,如果说我要在该内存空间中存储1,000个int指针,我是否需要N = 1000 * sizeof(int *);?

嗯,从技术上讲,您需要拥有n * sysconf(PAGESIZE) == N >= 1000 * sizeof(int*);但是,为什么要共享整数 pointers ?除非您有这些 pointers 指向(另一个)共享内存区域,否则在使用这些指针的每个进程中该地址都位于同一地址,因此共享 pointers 几乎是没有用的。当然,在fork之后,进程的地址空间是相同的,但是execve将取消映射所有先前的映射,并且您必须将非匿名mmap与{{1 }}和使用MAP_FIXED获得的filedescriptor,并使用memfd_create的第一个参数精确地将其映射到(可能会失败或过度映射先前存在的映射)。

您可以合理地共享的是偏移量大量数据

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

  

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

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