对于我必须要做的项目,我必须使用:
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个字节?
谢谢,我很感激。
答案 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
分配的一样。将指针转换为您认为合适的任何类型,然后照常使用它。