我对同花顺行为特别感兴趣。
假设我们使用CreateFileMapping()创建了一个MMF,并使用零偏移量的MapViewOfFile()打开了两个视图V1和V2。
然后我将某些内容写到A = V1 + a,并将一些内容写到B = V2 + b,这样A和B属于不同的物理内存页。
然后,如果我使用FlushViewOfFile(V1,0)刷新整个第一个视图,第二个视图的脏页也会受到影响吗?
我的目标是拥有同一文件的2个视图,其中第一个视图用于非常小的写入和非常频繁的刷新,而第二个视图用于大量写入,并且仅偶尔刷新一次。
>重要的是刷新小写不会引起大写的刷新。
这是默认行为吗?如果没有,该如何实现?
谢谢
答案 0 :(得分:0)
CreateFileMappingA,另请参见CreateProcess,DuplicateHandle和OpenFileMapping函数。
“创建文件映射对象实际上并不将视图映射到进程地址空间。MapViewOfFile和MapViewOfFileEx函数将文件的视图映射到进程地址空间。
一个重要的例外,从同一文件支持的任何文件映射对象派生的文件视图在特定时间是一致的或相同的。 保证了流程中的视图和不同流程所映射的视图的一致性。
该异常与远程文件有关。尽管CreateFileMapping与远程文件一起使用,但不能使它们保持一致。例如,如果两台计算机都将文件映射为可写文件,并且都更改同一页面,则每台计算机只能看到自己对页面的写入。磁盘上的数据更新后,不会合并。”
“刷新一定范围的映射视图启动,将该范围内的脏页写入磁盘。脏页是指自文件视图被映射以来其内容已更改的页面。 FlushViewOfFile 函数不会刷新文件元数据,并且等到从基础硬件磁盘缓存中刷新所做的更改并将其物理写入磁盘后,它才等着返回。文件的元数据,并确保它们已物理写入磁盘,请调用FlushViewOfFile,然后调用FlushFileBuffers函数。”
因此,当您关闭UnmapViewOfFile中的视图时
” 进程完成文件映射对象后,应使用每个文件视图的UnmapViewOfFile函数销毁其地址空间中的所有文件视图。
取消映射文件的映射视图会使该视图在进程的地址空间中占用的范围无效,并使该范围可用于其他分配。它将删除作为流程工作集一部分的每个未映射虚拟页面的工作集条目,并减小流程的工作集大小。 它还会减少相应物理页面的共享计数。
未映射视图中的已修改页面在其共享计数达到零之前不会写入磁盘,换句话说,直到它们被取消映射或从所有进程的工作集中修剪掉共享页面。即使这样,修改后的页面也会被“懒惰”地写入磁盘。也就是说,修改可能会缓存在内存中,并在以后写入磁盘。为了最大程度地减少断电或系统崩溃时数据丢失的风险,应用程序应使用FlushViewOfFile函数显式刷新修改后的页面。”