【问题标题】:How portable is mmap?mmap 的便携性如何?
【发布时间】:2010-01-25 23:36:51
【问题描述】:

我一直在考虑使用mmap 来读取文件,并且想知道它的便携性如何。 我正在 Linux 平台上进行开发,但希望我的程序可以在 Mac OS X 和 Windows 上运行。

我可以假设mmap 在这些平台上工作吗?

【问题讨论】:

  • 虽然我的回答没有解决 mmap 的可移植性方面,但 Boost 在 Boost.Interprocess 和 Boost.Iostreams 中提供了替代方案,它们似乎可以在 Linux 上像 Windows 一样工作。

标签: windows linux macos mmap


【解决方案1】:

mmap() 函数是一个 POSIX 调用。它在 MacOS X(和 Linux、HP-UX、AIX 和 Solaris)上运行良好。

问题区域将是 Windows。我不确定POSIX“兼容性”子系统中是否有_mmap() 调用。它很可能存在 — 但名称会带有前导下划线,因为 Microsoft 对命名空间有另一种看法,并认为 mmap() 会侵入用户名空间,即使您要求使用 POSIX 功能。您可以在另一个 SO 问题 (mmap() vs reading blocks) 中找到替代 Windows 界面 MapViewOfFile() 的定义和关于性能的讨论。

如果您尝试在 32 位系统上映射大文件,您可能会发现内存中没有足够的连续空间来分配整个文件,因此内存映射将失败。不要以为它会起作用;决定失败时的后备策略。

【讨论】:

    【解决方案2】:

    如果您依赖将大量大文件映射到地址空间,则使用 mmap 读取文件是不可移植的 - 32 位系统很容易没有一个大的可用空间 - 例如 1G - 可用的地址空间,因此 mmap 1G 映射会经常失败。

    【讨论】:

      【解决方案3】:

      内存映射文件的原理是相当可移植的,但是您在 Windows 上没有 mmap()(但存在诸如 MapViewOfFile() 之类的东西)。你可以看一下 python mmap 模块的 c 代码,看看它们是如何在各种平台上实现的。

      【讨论】:

        【解决方案4】:

        我认为 UNIX 上的内存映射 io 不可用于交互式应用程序, 因为它可能会导致 SIGSEGV/SIGBUS (如果文件同时被其他进程截断)。 忽略 setjmp/longjmp 这样的病态“解决方案” 除了在获得 SIGSEGV/SIGBUS 后终止进程外,没有什么可以做的。 将此类信号转换为异常的新 G++ 功能 似乎主要用于苹果操作系统, 由于描述说明,需要运行时支持此 G++ 功能 并且在任何地方都找不到有关此 G++ 功能的信息。 我们可能需要再等几年,直到像 Windows 一样的结构化异常处理才能在 Windows 上找到,因为 20 多年来它进入了 UNIX。

        【讨论】:

        • 虽然你没有直接回答这个问题,但我觉得这真的很有帮助,谢谢。
        • 内存映射 io 不能用于 UNIX 上的非平凡应用程序会影响内存映射 io 的可移植性
        • 如果您知道应用程序会崩溃,为什么还要让其他进程截断您的文件? (为了防止用户无能,有相当标准的基于 fcntl() 的锁定机制。)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-24
        • 2020-08-03
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多