澄清Windows中虚拟内存管理器如何获取内存映射文件数据

时间:2017-12-24 07:30:57

标签: c winapi window

说,如果我有一个大文件,我会映射到我的进程的虚拟地址空间:

//Error handling is omitted for brevity
HANDLE hFile = CreateFile(L"path-to\\file", 
            GENERIC_READ,
            FILE_SHARE_READ, NULL, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
char* pAddress = (char*)MapViewOfFile(hFileMapping,
            FILE_MAP_READ, 0, 0, 0);

//And get the data
char data_byte = pAddress[offset];

//Then remember to do the cleanup ....

内核虚拟内存管理器何时从磁盘上的文件中读取实际数据(或执行I / O操作以从硬盘驱动器中获取数据):

A)调用MapViewOfFile

B)当我使用pAddress[offset]

访问它时

如果上面的答案是B,那么第二个问题是 - 当它获取数据时:

C)是否读取整个文件,或

D)只有包含页面(4K大小,左右)?

1 个答案:

答案 0 :(得分:3)

B D

当您为视图调用'<a class="button" href="{}?product_id={}">Reorder</a>', ... reverse('admin:inventory_reorder_add'), obj.pk MapViewOfFile)内核保留范围虚拟但未将其与实际物理页面关联时(因此不会在开始时分配物理页面)。当您第一次访问部分视图中的某个地址时 - 因为它尚未与物理页面关联(PTE无效) - cpu将生成异常。系统处理此异常时,它会分配已经存在的物理页面,将虚拟地址与此页面关联,从文件中读取数据(如果由文件支持),并从指令继续执行,从而生成异常。

因此,当您将数据映射到内存中时,系统不仅仅是从文件中读取数据,而是等到您第一次访问它时。并且在第一次访问时 - 它读取数据而不是整个部分范围(部分可以不是从文件开始和结束而不是在文件结束)但只有访问页面(可能是几页)