C++ 内存映射IO概念详细信息
我试图找出在Windows中编写文件的最佳方法。为此,我一直在运行一些内存映射测试,试图弄清楚发生了什么以及我应该如何组织事情 场景:该文件打算在单个进程、多个线程中使用。您应该将线程视为处理文件存储的辅助线程;其中一些会读,一些会写——在某些情况下,文件会增长。我希望我的状态能够在进程崩溃和操作系统崩溃中幸存下来。文件可以很大,例如:1 TB 在阅读了大量有关MSDN的内容后,我编写了一个小测试用例。我基本上做的是:C++ 内存映射IO概念详细信息,c++,windows,multithreading,operating-system,mmap,C++,Windows,Multithreading,Operating System,Mmap,我试图找出在Windows中编写文件的最佳方法。为此,我一直在运行一些内存映射测试,试图弄清楚发生了什么以及我应该如何组织事情 场景:该文件打算在单个进程、多个线程中使用。您应该将线程视为处理文件存储的辅助线程;其中一些会读,一些会写——在某些情况下,文件会增长。我希望我的状态能够在进程崩溃和操作系统崩溃中幸存下来。文件可以很大,例如:1 TB 在阅读了大量有关MSDN的内容后,我编写了一个小测试用例。我基本上做的是: 使用file\u FLAG\u NO\u BUFFERING\124; fi
file\u FLAG\u NO\u BUFFERING\124; file\u FLAG\u WRITE\u to
打开文件(CreateFile
)CreateFileMapping
)MapViewOfFile
)(从STORAGE\u PROPERTY\u QUERY
)。我打算使用的模式是读+写diskmon
这样的工具有很好的理由不起作用),所以我决定在这里提问。我基本上想知道的是:我如何在我的场景中最好地使用这些结构
如果我理解正确,这或多或少是正确的方法;但是,我不确定CreateFileMapping
与MapViewOfFile
的确切作用,以及这是否适用于多个线程(例如,刷新到磁盘时的写入顺序)
CreateFileMapping
重新打开它MapViewOfFile
(似乎限制为2GB)对每一块进行处理并再次取消映射内存映射文件通常最适合读取;不写。您面临的问题是,在进行映射之前,必须知道文件的大小 你说: 在某些情况下,文件将增长 这实际上排除了内存映射文件 在Windoze上创建内存映射文件时,您正在创建自己的页面文件,并将内存范围映射到该页面文件。这往往是读取二进制数据的最快方法,尤其是在文件连续的情况下
对于写入,内存映射文件是有问题的。当您需要文件标记写入和“在操作系统崩溃后生存”时,使用MMF是完全不合适的。您无法控制将MMF更改刷新到磁盘的确切时间。“别这么做!”汉斯帕桑很有趣。我开始探索内存映射,因为我在一些论文中读到一些数据库将其用于磁盘IO(并且它们保证了ACID的“持久性”)。我还在PostgreSQL bugreports()上读到,他们停止使用
FlushFileBuffers
非常糟糕。那么,如果这两种方法都不适用,您在这里有什么建议作为解决方案?使用WriteFile和ReadFile有什么问题?因为你已经关闭了缓冲,所以在我看来,至少就操作系统而言,它们提供了你想要的保证。(如果您也想对电源故障保持健壮性,那么底层硬件可能尊重这些保证,也可能不尊重这些保证,但如果不这样做,您就无能为力。)(顺便说一句,我相信MapViewOfFile将适用于大于2GB的视图,当然前提是您构建的是64位。在这种情况下没有实际意义,因为正如Hans所说,您将无法获得所需的保证。)@HarryJohnston写文件没什么问题,我只是想找出最好的方法。所以,让我直截了当地说:你们基本上告诉我的是,我应该坚持使用它们,再加上无缓冲和写入。(或者,不要使用这些标志,而是显式使用FlushFileBuffers
——任何性能最好的)。正确吗?