内存映射文件 内存映射文件定义把磁盘上的文件映射到物理页再映射进进程虚拟地址空间直接操作虚拟地址指针就等于读写文件✅优点使用简单指针读写省去反复 ReadFile/WriteFile 调用大文件性能高减少 IO 拷贝天然支持多进程共享两种使用场景①映射磁盘文件内容最终落盘②匿名映射INVALID_HANDLE_VALUE纯内存共享不绑定文件前面学的 IPC 共享内存文件映射读写完整流程绑定磁盘文件CreateFile 打开磁盘文件HANDLE hFileCreateFile(LC:\\Test.txt,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);CreateFileMapping 创建文件映射内核对象传入文件句柄HANDLE hMapCreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);MapViewOfFile 映射视图拿到虚拟内存指针LPVOID lpAddrMapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);读写直接对lpAddr指针操作*(PDWORD)lpAddr0x41414141;//写入 AAAA强制刷入磁盘FlushViewOfFile(lpAddr,4)不调用 Flush修改不会立刻写磁盘系统会在合适时机自动刷盘资源释放顺序严格不能乱UnmapViewOfFile(lpAddr);//1.解除虚拟地址映射CloseHandle(hMap);//2.关闭映射内核对象句柄CloseHandle(hFile);//3.关闭原始文件句柄内存映射文件实现进程间共享绑定磁盘文件● 多个进程打开同一个磁盘文件的映射对象共享同一份物理页● 进程 A 修改内存进程 B 能读到新值修改会同步到磁盘文件● 多进程映射后的虚拟地址可以不一样但指向同一个物理页区别匿名共享内存匿名共享内存不关联磁盘文件文件映射共享会把改动保存到硬盘写时复制 FILE_MAP_COPY底层原理创建映射时保护属性PAGE_WRITECOPYMapViewOfFile 用FILE_MAP_COPY● 读的时候所有进程共用同一份原始物理页● 写的时候系统单独复制被修改的这一页4KB 一页当前进程在副本上修改● 修改只对本进程生效不会影响其他进程也不会写回原磁盘文件实验现象● 进程 A 修改映射内存为0x41414141(“AAAA”)● 进程 B 读取依旧是原始数据0x30303030(“0000”)● 磁盘上文件内容完全不变典型用途Windows 系统 DLLkernel32.dll 等所有进程共用一份物理页防止一个进程修改 DLL 代码影响全部进程调试器下断点修改代码为0xCC INT3仅调试进程生效不破坏原始文件、不影响别的进程权限宏对比访问宏效果FILE_MAP_READ只读不能写FILE_MAP_WRITE读写修改同步到文件FILE_MAP_ALL_ACCESS等价 FILE_MAP_WRITE读写FILE_MAP_COPY写时复制修改仅本进程可见不改原文件总结内存映射文件磁盘文件→物理页→进程虚拟地址指针直接读写文件资源释放顺序UnmapViewOfFile → CloseHandle (hMap) → CloseHandle (hFile)FlushViewOfFile强制将内存修改写入磁盘不调用会缓存延迟写入FILE_MAP_COPY 写时复制读共享写复制页面修改隔离不改动原文件两种共享○ 普通文件映射多进程共享物理页修改同步到磁盘文件○ 匿名映射INVALID_HANDLE_VALUE共享内存不关联磁盘文件用于 IPC示例完整代码#includewindows.h#includestdio.hintmain(){HANDLE hFileCreateFile(LC:\\test.txt,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);HANDLE hMapCreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);LPVOID pBufMapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);*(PDWORD)pBuf0x41414141;FlushViewOfFile(pBuf,4);//强制刷盘getchar();//暂停用来做多进程实验观察UnmapViewOfFile(pBuf);CloseHandle(hMap);CloseHandle(hFile);return0;}