FlushViewOfFile Under the Hood

来源:互联网 发布:战地2武器解锁软件 编辑:程序博客网 时间:2024/05/19 17:56

人老精,鬼老灵。程序写到最后不再是是否可以实现的问题。相反,你会不断的平衡和权衡用户的需求以及程序的性能之间的关系。同时在Windows开发面临的另一个问题就是是否应该相信微软的话以及文档。因为微软底层的实现有太多的东东我们不知道,加之其模棱两可的MSDN.

最近在修改一个问题,是关于Registry Lazy Writing 的,原程序把每次的操作结果写在Registry 中,如果碰到系统Crash那么什么都没了。我的解决方案是使用内存映射文件代替Registry。
像所有的MS RULE 一样,我天真的写下了如下的代码:
m_hFile = CreateFile( pszFileName,
                                  GENERIC_READ 
| GENERIC_WRITE,
                                  FILE_SHARE_READ 
| FILE_SHARE_WRITE,//Change for Windows 2003 SP2 
                                  NULL, //security
                OPEN_ALWAYS, // creation mode
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
                NULL); 
//template
        
if(m_hFile != INVALID_HANDLE_VALUE)
{
   hFileMapping 
= CreateFileMapping(m_hFile,NULL,PAGE_READWRITE,0sizeof(long),SHARED_MEMO_FILE_NAME);
   
if(NULL != hFileMapping)
       m_pCounter 
= (long*)MapViewOfFileEx(hFileMapping,FILE_MAP_WRITE,00,sizeof(long),0);
}
        
CloseHandle(hFileMapping);
    
return m_pCounter != NULL;
 
我很清楚的了解,如果没有FlushViewOfFile 这个函数每次将结果写回到物理文件上,那么我的解决方案和前者比起来没有任何优势。
FlushViewOfFile 在MSDN中的解释是这样的:
Flushing a range of a mapped view causes any dirty pages within that range to be written to the disk. Dirty pages are those whose contents have changed since the file view was mapped.
一切看起来都很完美。m_pCounter 操作之后使用FlushViewOfFile 将内存中修改的页面写回到磁盘。就像这样:
*m_pCounter++;
BOOL b = FlushViewOfFile(const_cast<long*>(m_pCounter), sizeof(long));
之后的单元测试,让我不禁失望起来。
如果在*m_pCounter++ 之后将mapping file 删除那么再次执行FlushViewOfFile回出现什么结果?
按照MSDN的叙述,既然FlushViewOfFile是对磁盘文件操作那么文件丢失后,返回值一定是FALSE.
但是结果不是。说明什么问题?说明FlushViewOfFile 也是Lazy writing, 说明FlushViewOfFile 只是简单的将dirty page写回到物理内存,之后又File Cache Manager 写回到Disk.说明MSDN在有意隐藏实现的细节。
那么是不是我的系统环境的问题?也许我冤枉了MS SDK.OKAY,再做一个Test 好了。我加上了一下语句:
*m_pCounter++;
BOOL b = FlushViewOfFile(const_cast<long*>(m_pCounter), sizeof(long));
b = FlushFileBuffers(m_hFile);// m_hFile’s the handle of Mapping file.
过程和上面一样,在FlushViewOfFile之前删除了Mapping file, FlushViewOfFile依旧不知道廉耻的返回TRUEJ.但是FlushFileBuffers 返回的是FALSE.
这次我更加坚信的判断-FlushViewOfFile 也是Lazy writing只有FlushFileBuffers才会calling File Cache Manager将文件写入Disk.
原创粉丝点击