我们在 mmap 中将文件描述符设置为 -1 的场景是什么?

ANT*_*ONY 4 c linux mmap linux-kernel

为什么 mmap 比读写更好

还有一个类似的帖子

我的问题如下:在某些情况下,人们使用 mmap 而不是从文件中读取。一种这样的代码是:

 *mapping = mmap(NULL, *mapping_size, PROT_READ | PROT_WRITE,
      MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
Run Code Online (Sandbox Code Playgroud)

上面的代码试图分配大量的内存。我想知道在这种情况下 mmap 是做什么的,它是如何工作的。每个人都在谈论 mmap wrt 文件的优势。但是这些 fd 设置为 -1 的代码很常见。这是什么意思,这样做有什么好处。?我希望有人能消除我的疑问,由于含糊不清,我无法完全提出疑问。

谢谢

Bac*_*con 6

让我尝试解决这个问题的一部分,特别是:

但是这些 fd 设置为 -1 的代码很常见。这是什么意思,这样做有什么好处。?

====

mmap()用于在虚拟内存中的某处(可以由发出 mmap 的进程引用的某处)创建内存映射。指定文件描述符允许将内存换出到磁盘。此外,由于只有当前访问的文件区域必须加载到内存中,因此可以 mmap 大小始终大于物理内存和磁盘(交换)空间的文件。请参阅GNU 文档

有几个用例不希望指定文件描述符并映射匿名内存区域。其中之一可能是扩展进程的堆。另一个是愿意共享数据而不将它们保存在文件中,因此不会产生额外的 I/O 开销。再次来自 GNU 文档:

MAP_ANONYMOUS

MAP_ANON

此标志告诉系统创建匿名映射,而不是连接到文件。filedes 和 off 将被忽略,并且该区域 > 用零初始化。

在某些系统上,匿名映射被用作扩展堆的基本原语。它们还可用于在多个 > 任务之间共享数据而无需创建文件。

在某些系统上,使用私有匿名 mmaps 比对大块使用 malloc 更有效。这不是 GNU > C 库的问题,因为包含的 malloc 会在适当的情况下自动使用 mmap。

但是,请注意匿名 mmap-ed 内存只能从进程内部或由其 child(ren) 访问。由于内存是匿名的,因此无法引用它!必须使用shm_open()将共享内存包装在一个对象中并使其可用于其他进程。请参阅shm_open()手册页中的专家(粗体部分是我的):

shm_open() 创建并打开一个新的或打开一个现有的 POSIX 共享内存对象。POSIX 共享内存对象实际上是一个句柄,无关进程可以使用它来 mmap(2) 共享内存的同一区域

fd = -1只是某些系统接受您的分配并忽略文件描述符的合规性。请参阅 Linux 上 man mmap 的专家:

MAP_ANONYMOUS

映射不受任何文件的支持;它的内容被初始化为零。fd 和 offset 参数被忽略;但是,如果指定了 MAP_ANONYMOUS(或 MAP_ANON),某些实现要求 fd 为 -1,并且便携式应用程序应确保这一点。MAP_ANONYMOUS 与 MAP_SHARED 结合使用仅在 Linux 内核 2.4 之后才被支持。

您提到的问题之一有一些关于此系统特定行为的参考。


Sti*_*tad 0

它是一种用于将动态(新)内存映射到应用程序中的方法。对于实现 malloc() (和朋友)的 libc,这是实际分配内存的一种可能的技术