答案 0 :(得分:1)
mmap()系统调用允许您进行文件支持的映射或匿名映射。
void * mmap(void * addr,size_t lengthint" prot",int" flags,int fd, off_t offset)
文件支持的映射 - 在linux中,存在一个文件 / dev / zero ,它是0字节的无限来源。您只需打开此文件,并将其描述符传递给带有相应标志的 mmap() 调用,即MAP_SHARED
,如果您希望共享内存其他流程或MAP_PRIVATE
如果您不想分享。
实施例 -
.
.
if ((fd = open("/dev/zero", O_RDWR)) < 0)
printf("open error");
if ((area = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0)) == MAP_FAILED)
{
printf("Error in memory mapping");
exit(1);
}
close(fd); //close the file because memory is mapped
//create child process
.
.
引用mmap()的手册页: -
文件映射的内容(与匿名映射相对; 请参阅下面的MAP_ANONYMOUS),使用长度字节开始初始化 在文件引用的文件(或其他对象)中的偏移量偏移处 描述符fd。 offset必须是返回的页面大小的倍数 通过sysconf(_SC_PAGE_SIZE)。
在我们的例子中,它已经用零(0s)初始化。
引用W. strong Stevens,Stephen A. Rago II Edition 在UNIX环境中的高级编程一书
以我们已经显示的方式使用/ dev / zero的优点是 在我们调用mmap创建之前,实际文件不需要存在 映射区域。映射/ dev / zero会自动创建映射区域 指定大小。这种技术的缺点在于它 仅适用于相关流程。但是,通过相关流程, 使用线程可能更简单,更有效(第11章 和12)。请注意,无论使用哪种技术,我们仍然如此 需要同步对共享数据的访问
在对mmap()
的调用成功后,我们创建了一个子进程,它将能够看到对映射区域的写入(正如我们指定的MAP_SHARED
标志)。
匿名映射 - 我们在上面做的类似事情可以使用匿名映射完成。对于匿名映射,我们为mmap指定MAP_ANON
标志,并将文件描述符指定为-1 。
生成的区域是匿名的(因为它不通过文件描述符与路径名相关联)并创建可与后代进程共享的内存区域。
优点是我们不需要任何文件来映射内存,也可以避免打开和关闭文件的开销。
if ((area = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
printf("Error in anonymous memory mapping");
因此,这些文件支持的映射和匿名映射必须仅适用于相关进程。
如果您在不相关的进程之间需要这个,那么您可能需要使用shm_open()
创建命名共享内存,然后您可以将返回的文件描述符传递给mmap()
。