Linux 中的 mmap 文件支持映射与匿名映射

mmap File-backed mapping vs Anonymous mapping in Linux

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

void *mmap(void *addr, size_t lengthint " prot ", int " flags ,int fd, off_t offset)

File-backed mapping- 在 linux 中,存在一个无限文件 /dev/zero 0字节的来源。您只需打开此文件,然后将其描述符传递给带有适当标志的 mmap() 调用,即 MAP_SHARED 如果需要由其他进程共享的内存或 MAP_PRIVATE 如果您不想共享。

Ex-

     .
     .
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() 的手册页:-

The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes starting at offset offset in the file (or other object) referred to by the file descriptor fd. offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).

在我们的例子中,它已经用零(0)初始化。

引用 W. Richard Stevens 着的 UNIX 环境中的高级编程,Stephen A. Rago II 版

中的文字

The advantage of using /dev/zero in the manner that we've shown is that an actual file need not exist before we call mmap to create the mapped region. Mapping /dev/zero automatically creates a mapped region of the specified size. The disadvantage of this technique is that it works only between related processes. With related processes, however, it is probably simpler and more efficient to use threads (Chapters 11 and 12). Note that regardless of which technique is used, we still need to synchronize access to the shared data

调用 mmap() 成功后,我们创建一个子进程,它将能够看到对映射区域的写入(正如我们指定的 MAP_SHARED 标志)。

匿名映射 - 可以使用匿名 mapping.For 匿名映射来完成我们在上面所做的类似事情,我们将 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().