【Windows核心编程笔记】第十七章 内存映射文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhao3132453/article/details/91047210

适用情况:

加载exe或者dll,大量节省页交换文件的空间和程序启动时间

避免缓存,直接访问磁盘上的数据文件

最高效的进程间共享数据方法

 

映射到内存的可执行文件和dll

同一个exe或dll的多个实例不会共享静态数据(默认情况)

在同一个exe或dll的多个实例间共享静态数据(创建共享段)

       Dumpbin工具查看段内容

 

       #pragma data_seg(“shared”)

       Int I = 0;

       #pragma data_seg()

       创建一个段,并把初始化的部分放到段里边,不过可以用allocate放入未初始化数据

       单独段的作用一般来说是为了使用共享变量

 

       #pragma comment(linker,”/SECTION:shared,RWS”) 共享变量

 

      

映射到内存的数据文件

比如颠倒文件内容:

方法1:一个文件,一块内存(理论简单,有不能处理大文件、过程中断内容破坏的问题)

方法2:两个文件,一块缓存(创建长度为0的文件,通过一次次向缓存中写入较小的一部分,一直到完成整个过程,有速度慢、两个文件占用空间大了一倍的问题)

方法3:一个文件,两块缓存(首部的一部分放入一块缓存,尾部的一部分放入另一块缓存,颠倒后,尾部缓存的放到首部,首部缓存的放到尾部,一直到完成,有实现复杂、中断可能破坏文件的问题)

方法4:一个文件,不要缓存(_tcsrev系统处理,使用内存映射,但是断电仍可能会导致数据破坏)

 

使用内存映射文件

使用过程:

创建或打开文件内核对象(CreateFile)

创建文件映射内核对象(CreateFileMapping)

文件映射对象的部分或全部映射到进程的地址空间(MapViewOfFile)

 

取消映射(UnmapViewOfFile)

关闭文件映射内核对象

关闭文件内核对象

 

用内存映射文件来处理大文件

只映射文件的一个视图,这个视图只包含文件的一小部分数据。从文件开头开始映射,完成第一个视图后撤销,循环处理剩下的部分

 

内存映射文件和一致性

系统只保证同一文件映射对象的多个视图间数据保持一致,而不保证不同文件映射对象的各个视图一致

只读文件不存在一致性,所以非常适合内存映射文件。但是绝对不应该使用内存映射文件来跨网络共享可写文件,因为无法保证数据视图的一致性(一台机器更新文件,另一台机器不知道)

 

给内存映射文件指定基地址

MapViewOfFileEx 最后一个参数指定一个目标地址(用户模式分区中的地址)

此函数适用于内存映射文件跨进程共享数据

 

内存映射文件的实现细节

两个进程映射同一个文件映射对象的视图,调用MapViewOfFile返回的地址可能不同

 

用内存映射文件在进程间共享数据

共享数据方式:RPC、COM、OLE、DDE、Windows消息(尤其是WM_COPYDATA)、剪贴板、邮槽、管道、套接字等

同一机器上,以上方式的底层都会用内存映射文件

 

以页交换文件为后备存储器的内存映射文件

不再调用CreateFile,调用CreateFileMapping时把INVALID_HANDLE_VALUE作为hFile参数传入即可

所以,CreateFile要时时检查返回值,避免意想不到的情况(创建文件映射的时候以页交换文件为后备存储器,而不是磁盘文件)

 

稀疏调拨的内存映射文件

CreateFileMapping      fdwProtect参数指定SEC_RESERVE或SEC_COMMIT

猜你喜欢

转载自blog.csdn.net/zhao3132453/article/details/91047210
今日推荐