【问题标题】:mmap of files can be done in any other way except page level mapping?文件的 mmap 可以通过页面级映射以外的任何其他方式完成吗?
【发布时间】:2017-02-15 08:36:05
【问题描述】:

最近在一次采访中,有人问我mmap是否可以直接以二进制模式对程序进行映射;没有页面参考。

我认为这是不可能的,因为它

允许应用程序将文件映射到内存中,这意味着有 一个内存地址和一个字之间的一一对应关系 文件。然后程序员可以直接通过内存访问文件, 与任何其他内存驻留数据块相同——甚至 可以允许对内存区域的写入透明地映射 回到磁盘上的文件

在不涉及分页的情况下访问文件听起来是错误的。

我仍然想知道 mmap 是否可以通过页面方式以外的任何其他方式将文件映射到内存中。

=====
the page way
=====

页面是最小的内存单元,可以有不同的 权限和行为。因此,页面是构建块 内存映射,这反过来又是构建块 进程地址空间。 mmap() 系统调用在页面上运行。两个都 addr 和 offset 参数必须在页面大小上对齐 边界。也就是说,它们必须是页面大小的整数倍。

因此,映射是页面的整数倍。如果 调用方提供的 len 参数未在页面上对齐 边界——可能是因为底层文件的大小不是倍数 页面大小——映射向上舍入到下一整页

【问题讨论】:

  • 映射文件的页面方式是什么?
  • @Marian 添加了问题。
  • 对我来说这个mapping of the program in binary mode directly; without page reference 很不清楚。
  • 在“旧时代”(32 位)中,分段可以用作(或连同)分页来创建文件映射的替代方法(但是 linux mmap() 不支持) .这甚至是字节粒度。但是 x86_64 很大程度上放弃了对此的支持。

标签: c memory-management mmap


【解决方案1】:

如果我们使用page的维基百科定义,所有内存映射都涉及页面级映射:

页、内存页或虚拟页是固定长度的连续虚拟内存块,由页表中的单个条目描述。它是虚拟内存操作系统中用于内存管理的最小数据单位。

man 2 mmap 手册页所述,

mmap() 在调用进程的虚拟地址空间中创建一个新的映射。

映射由页表中的条目定义。

所以,本质上,mmap() 是一个在页面级别管理虚拟内存的工具。


面试官可能想知道你是否理解低级 I/O(read()write())和文件支持的内存映射行为之间的区别。

如果您使用O_DIRECT 标志打开文件,内核会尝试绕过页面缓存将数据直接传输到用户空间缓冲区。

由于内存映射的工作方式,带有或不带有O_DIRECT 标志的支持文件open()ed 对内存映射没有影响。

(MAP_SHARED/MAP_PRIVATE 标志会影响用于映射的访问部分的内存是否保留在页面 cache 中。通常,Linux 内核使用副本-on-write 方法:页面在页面缓存中保持只读状态,直到第一次写入访问。此时,私有映射被复制到新页面(或被驱逐),并且共享映射被标记为读写。它是有点复杂,但效率很高。不过,这一切也都依赖于虚拟内存分页。)

甚至可以构建一个完全没有支持的内存映射(PROT_NONE 映射)。对映射的任何访问都会导致内核生成SIGBUS 信号(给尝试访问的线程),该信号可以被进程捕获。信号处理程序可以解码和跳过指令,从而模拟内存访问。它甚至可以使用O_DIRECT 从文件中读取一个或多个字节。同样,映射基于虚拟内存,因此也基于页面;没有用于映射的 RAM,而是模拟所有访问。这很少使用,因为它慢得难以想象。

【讨论】:

    【解决方案2】:

    分页是(至少在现代操作系统和架构上)通过物理内存管理的机制。

    我建议你在这个问题上read more,但基本上物理内存(使用物理地址寻址)是使用虚拟地址从内核和用户空间访问的.

    物理虚拟地址之间的映射通常使用MMU在硬件中完成,并使用页面进行组织。使用这个概念,内存页面定义了一系列物理地址和虚拟地址之间的映射。

    操作系统还在低级页面管理之上添加了几个层,mmap 是分页系统的用户界面,允许您操作页面。 特别是,它允许您将内存页面(请记住,一系列虚拟地址)映射到物理内存以外的其他内容,例如存储在硬盘驱动器上的文件。

    总之,唯一您可以使用内存的方式是通过此分页系统,因此要回答您的问题,访问某些内容(文件、物理内存或其他任何内容)没有任何意义) “以除页面方式以外的任何其他方式”。

    【讨论】:

      猜你喜欢
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 2014-12-05
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多