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

本文深入探讨了内存映射文件技术,详细介绍了其在节省页交换文件空间、加速程序启动、高效进程间数据共享等方面的应用。文章还讨论了如何在多个实例间共享静态数据,以及使用内存映射文件处理大文件、保证数据一致性和指定基地址的方法。此外,还对比了多种文件处理策略,并介绍了使用内存映射文件进行进程间通信的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

适用情况:

加载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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值