ANT*_*ONY 4 c linux mmap linux-kernel
我的问题如下:在某些情况下,人们使用 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 的代码很常见。这是什么意思,这样做有什么好处。?我希望有人能消除我的疑问,由于含糊不清,我无法完全提出疑问。
谢谢
让我尝试解决这个问题的一部分,特别是:
但是这些 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 之后才被支持。
您提到的问题之一有一些关于此系统特定行为的参考。