适用情况:
加载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