跨平台的内存映射文件IO

16
我花了一些时间研究内存映射IO,因为我正在处理一些非常大的(TB级别)文件,并且我想要将它们的部分映射到内存中进行读写,充分利用操作系统级缓存。我正在编写的软件需要在Unix / Linux和Windows下工作...性能至关重要。
我发现了boost :: iostreams :: mapped_file_source和boost :: iostreams :: mapped_file_sink,它们提供了我正在寻找的大多数设施。我想要但没有找到的功能包括:
- 强制将写入的数据同步到磁盘上(Unix上的msync(2); Windows上的FlushViewOfFile) - 锁定文件以防止两个进程同时尝试写入同一个文件(或在文件仍在被写入时进行读取..) - 在创建时控制文件的属性(Unix)
我能否使用"boost/iostreams/device/mapped_file.hpp"来做到这些事情?是否有其他平台无关的库更适合我的要求?我必须开发自己的跨平台库才能获得这种灵活性吗?

1
顺便提一下,“内存映射I/O”通常是指使用地址(也称为内存映射)(类似于使用指针)而不是使用特殊的处理器I/O指令来读取I/O端口。 - Thomas Matthews
1
说得好。我在谈论内存映射文件I/O [http://en.wikipedia.org/wiki/Memory-mapped_file] - 并已编辑标题以反映这一点。 - aSteve
3个回答

6

你可能是对的...但是,使用boost::interprocess,我无法看到如何(直接)以操作系统页面大小的块来访问数据... - aSteve
@aSteve,这个库支持内存映射文件,请参见:http://www.boost.org/doc/libs/1_48_0/doc/html/interprocess/managed_memory_segments.html#interprocess.managed_memory_segments.managed_mapped_files - Nim
是的,boost::interprocess支持(管理)内存映射文件...在这个上下文中,“管理”意味着通过malloc()访问文件中的空间。显然对于进程间通信非常有价值,但我需要一种更基本的“非托管?”方法来进行“原始”IO。我需要一个函数,返回一个指向包含任意文件偏移量的映射块的指针。boost::iostreams::mapped_file_*接口在这里非常理想...虽然它们不提供相同的同步/锁定灵活性。我已经阅读了interprocess文档-我看不出如何使用interprocess进行“原始”映射IO。 - aSteve
1
更新...我现在意识到你的意思是我应该使用boost::interprocess::file_mapping - 这个类很有道理。 - aSteve
@aSteve,抱歉,我以为你在意识到它后会去探索这个库! :) 看起来你现在已经去了!;) - Nim

2
这个问题很老,但在谷歌上排名第一。所以我会添加我知道的一些其他库。 mio 跨平台的C++11头文件库,用于内存映射文件IO。
- 看起来简单直接,但可能已经被放弃了。 llfio 用于C++标准的P1031低级文件I/O和文件系统库。
- 看起来是所有I/O库中最重要的一个。已通过boost同行评审(也称为折磨)。被提议作为C++标准库的补充。
我还可以证明boost::interprocess的有效性,过去我曾经使用过它。

0
几年前,我尝试使用boost的内存映射IO来写入稀疏文件,了解到UNIX无法像Windows那样提供类似于古老时代可用的结构化异常处理。我发现,boost的创始人也无法绕过这个问题:他们为映射内存的整个大小分配了磁盘空间,使文件变得非稀疏。当然,这需要时间和磁盘空间。

有趣。我也一直在使用Boost Interprocess与稀疏映射文件,它们运行得很好(我保证我从来没有拥有过PB级的内存或磁盘 :))。我也不太确定结构化异常与此有何关系。 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接