c - 总是在常规文件的 mmap 中添加 MAP_NORESERVE 标志?

标签 c linux operating-system mmap page-caching

根据mmapmanual :

MAP_NORESERVE

Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available.

据我了解,如果将常规文件映射到虚拟地址范围,则不需要任何交换空间。只有 MAP_ANONYMOUS 可能需要一些交换空间。

那么,在常规文件的 mmap 中始终添加 MAP_NORESERVE 标志是否正确?

更新:

更具体地说,当使用 MAP_SHARED 时,始终在常规文件的 mmap 中添加 MAP_NORESERVE 标志是否正确?

最佳答案

To my understanding, if a regular file is mapped into the virtual address range, there is no need for any swap space. Only MAP_ANONYMOUS may need some swap space.

这取决于 mmap 标志。如果常规文件映射为 MAP_PRIVATE那么内存区域从文件中初始化,但不由文件支持。如果系统决定换出其任何页面,则系统将需要交换空间来进行此类映射。

So, is it correct to always add MAP_NORESERVE flag in mmap for a regular file?

指定 MAP_NORESERVE 并不是不正确对于任何映射。这只是一个关于您希望对程序行为有什么保证的问题。

而且,你似乎从错误的方向看待这个问题。如果特定映射永远不需要交换空间,则无论标志如何,系统都不会为其保留交换空间。使用 MAP_NORESERVE 并没有什么坏处在这种情况下,但这也没有帮助,那么还有什么意义呢?

另一方面,如果您想确保映射不会因使用 MAP_NORESERVE 而失败那么最合适的做法是避免使用该标志。如果您愿意,您可以完全忽略它的存在,事实上,如果您想要最大的可移植性,您应该这样做,因为 MAP_NORESERVE是 POSIX 未指定的 Linux 扩展。


更新:

据我了解,您断言您可以通过 MAP_SHARED 重复观察现有文件的现有范围的成功映射。要求MAP_NORESERVE 。也就是说,两次此类映射尝试的不同之处仅在于是否MAP_NORESERVE。指定的结果将以您可以预测和可靠重现的方式为您产生不同的结果。

我觉得这令人惊讶,甚至可疑。我不希望页表映射到常规文件的现有区域的进程虚拟地址空间的页面与交换空间有任何关联,因此我不希望系统在以下情况下尝试为此类页面保留任何交换空间:它建立了一个映射,尽管有标志。如果您确实观察到不同的行为,那么我会将其归因于库或内核错误,您应该对此提出问题。

例如,考虑 GNU libc 手册,其中明确指出 a memory mapping can be larger than physical memory and swap space ,但没有记录 Linux 特定的 MAP_NORESERVE完全没有。

话虽如此,(在 Linux 上)指定 MAP_NORESERVE 并不是不正确。对于任何给定的内存映射。我预计它对于 MAP_SHARED 来说毫无意义。然而,映射常规文件的现有区域,因此我不认为定期使用该标志进行此类映射是好的做法,更不用说最佳做法了。另一方面,如果指定该标志可以解决库或内核错误,否则会干扰建立某些映射,那么我认为没有特别的理由避免这样做,但我希望每个此类使用都附有解释原因的文档注释使用该标志。

关于c - 总是在常规文件的 mmap 中添加 MAP_NORESERVE 标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60545558/

相关文章:

linux - pam-pgsql 与 sshd

linux - 如何仅在前一个返回 0 时才启动下一个 shell 脚本?

c++ - C/C++ 中的简单广播库/示例

C++ SQL 查询/为 C++ 封装的 SQL?

c - kernel/sched.c/context_switch() 是否保证每次进程切换时都会被调用?

operating-system - 如果 hyperion 将 amiga 发布到另一个平台,今天,它会生存吗?

visual-c++ - 如何用C/C++通过CPUID命令获取物理和虚拟地址位

cocoa - 简单的 cocoa 计算器

c - 如何修复 PrintUIEntry 返回错误代码 2

c++ - 为什么 C++ rand() 似乎只生成相同数量级的数字?