在Linux中,mmap文件映射和匿名映射有什么区别?

6
  • 文件映射和匿名映射的主要区别是什么。
  • 当我们需要进程间通信时,如何在文件映射和匿名映射之间进行选择。
  • 使用这些的优点和缺点是什么?
1个回答

6
系统调用允许您进行文件支持映射或匿名映射。

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()的man-page:
文件映射(相对于匿名映射,参见下文的MAP_ANONYMOUS)的内容是使用长度为length字节的文件(或其他对象)中从偏移量offset开始的数据进行初始化。offset必须是sysconf(_SC_PAGE_SIZE)返回的页面大小的倍数。
在我们的情况下,它已经被初始化为零。
引用W. Richard Stevens, Stephen A. Rago II Edition的书中的文本:
使用/dev/zero的优点是,在调用mmap创建映射区域之前不需要实际文件。映射/dev/zero会自动创建指定大小的映射区域。这种技术的缺点是仅适用于相关进程。但是,对于相关进程,使用线程可能更简单和更有效率(第11章和第12章)。请注意,无论使用哪种技术,我们仍然需要同步访问共享数据。
成功调用mmap()后,我们创建一个子进程,该进程将能够看到对映射区域的写入(因为我们指定了MAP_SHARED标志)。
匿名映射 - 可以使用匿名映射完成与上述类似的操作。对于匿名映射,我们将MAP_ANON标志指定为mmap,并将文件描述符指定为-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()

你说“这些基于文件的映射和匿名映射必须仅与相关进程一起使用。”我们为什么需要文件映射的mmap?与匿名映射相比,它如何帮助解决问题? - user1762571
1
当您选择文件支持的映射时,进程的虚拟地址空间将映射到该文件。因此,当您访问该内存时,您将读取已映射到该区域的文件。而匿名映射则将进程的虚拟内存区域映射到未由任何文件支持的区域。内容被初始化为零。在这方面,匿名映射类似于malloc,并且在某些malloc(3)实现中用于某些分配。 - Shubham_K
当您使用/dev/zero进行mmap()时,它与匿名映射相同。 - Shubham_K
https://en.wikipedia.org/wiki/Mmap 很好地解释了这两个概念。阅读关于内存可见性的部分以获取详细信息。它简短而精确。 - Shubham_K
谢谢。我理解在文件支持的映射中,进程的虚拟地址空间被映射到文件上。但是这有什么帮助呢?为什么我们不能只使用匿名映射?为什么我们需要文件支持的映射? - user1762571
以下这个线程可能能够解决你的问题 -https://dev59.com/4HVC5IYBdhLWcg3wixw0 - Shubham_K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接