0

我有一些代码(我无法更改)需要在本机 Win32 环境中工作。这段代码调用mmap()and munmap(),所以我使用CreateFileMapping(),MapViewOfFile()等创建了这些函数来完成同样的事情。最初这工作正常,并且代码能够按预期访问文件。不幸的是,代码继续到munmap()它不再需要的文件的选定部分。

x = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
... 
munmap(x, hdr_size);
munmap(x + foo, bar);
...

不幸的是,当您将指针传递到映射范围的中间时,UnmapViewOfFile()它会破坏整个映射。更糟糕的是,我看不出我如何能够检测到这是一个部分取消映射请求并忽略它。

我曾尝试调用VirtualFree()范围,但不出所料,这会产生 ERROR_INVALID_PARAMETER。

我开始认为我将不得不使用静态/全局变量来跟踪所有打开的内存映射,以便我可以检测并忽略部分取消映射,但我希望你有一个更好的主意......

编辑:

由于我上面不够明确: UnMapViewOfFile 的文档不能准确地反映该函数的行为。

取消映射整个视图并重新映射片段不是一个好的解决方案,因为您只能为新映射建议一个基地址,您无法真正控制它。的语义munmap()不允许更改仍映射部分的基地址。

我真正需要的是一种找到已映射内存区域的基地址和大小的方法。

编辑2:现在我以这种方式重申问题,看起来该VirtualQuery()功能就足够了。

4

2 回答 2

2

UnmapViewOfFile 的 MSDN Library 文档中非常明确:

lpBaseAddress
指向要取消映射的文件的映射视图的基地址的指针。该值必须之前调用 MapViewOfFile 或 MapViewOfFileEx 函数返回的值相同。

您通过取消映射旧映射并创建新映射来更改映射。取消映射的点点滴滴没有得到很好的支持,从内存管理的角度来看,它也不会有任何有用的副作用。您不想冒险使地址空间碎片化。

您必须以不同的方式执行此操作。

于 2010-09-08T01:17:18.330 回答
0

您可以跟踪每个映射以及客户端仍分配了多少页,并且仅在该计数器达到零时才释放映射。中间部分仍然会被映射,但这并不重要,因为客户端无论如何都不会访问该内存。

通过此接口创建内存映射的全局字典。当映射请求通过时,记录范围内的地址、大小和页数。当发出取消映射请求时,找出哪个映射拥有该地址,并通过正在释放的页数减少页数。当该计数达到零时,真正取消映射视图。

于 2010-09-16T15:44:37.407 回答