我一直在考虑使用mmap
进行文件读取,想知道它的可移植性如何。
我正在Linux平台上开发程序,但希望我的程序在Mac OS X和Windows上也能正常运行。
我能假设mmap
在这些平台上可以工作吗?
mmap()
函数是POSIX调用。它在MacOS X(以及Linux、HP-UX、AIX和Solaris)上运行良好。
问题出现在Windows上。我不确定POSIX“兼容性”子系统中是否有_mmap()
调用。很可能存在,但名称前面会有下划线,因为微软对命名空间有另一种看法,认为mmap()
即使你要求使用POSIX功能也会干扰用户命名空间。您可以在另一个SO问题(mmap()
vs reading blocks)中找到Windows接口的定义以及性能讨论,该问题讨论了另外一个可选的Windows接口MapViewOfFile()
。
如果您尝试在32位系统上映射大型文件,则可能发现没有足够的连续空间来将整个文件分配到内存中,因此内存映射将失败。不要假设它会成功;如果失败,请决定备用策略。
内存映射文件的原理相当可移植,但是在Windows上没有mmap()函数(但存在类似MapViewOfFile()的函数)。您可以查看Python mmap模块的c代码,以了解它们如何为各种平台执行此操作。
如果你依赖将大文件的大块映射到地址空间中,那么使用mmap读取文件是不具备可移植性的 - 32位系统可能没有足够的连续地址空间可供使用,比如1G,因此对于1G映射,mmap会经常失败。
我认为在UNIX上使用内存映射io不适用于交互式应用程序,因为这可能会导致SIGSEGV / SIGBUS(如果文件同时被其他进程截断)。 忽略诸如setjmp / longjmp之类的“病态”解决方案, 除了在收到SIGSEGV / SIGBUS后终止进程外,没有其他办法。 新的G ++功能将此类信号转换为异常 似乎主要是为苹果操作系统而设计的, 因为描述说明需要运行时支持此G ++功能, 并且无法在任何地方找到有关此G ++功能的信息。 我们可能需要等待几年,直到像Windows一样超过20年的结构化异常处理方式进入UNIX。