我想在 Windows 上调整内存映射文件的大小,而不会使从先前调用中检索到的指针无效MapViewOfFileEx
。这样,所有指向存储在整个应用程序中的任何文件数据的指针都不会因调整大小操作而失效。
我找到了解决问题的方法,但我不确定这种方法是否真的能保证在所有情况下都有效。
这是我的方法:我保留了一个大内存区域VirtualAlloc
:
reserved_pages_ptr = (char*)VirtualAlloc(nullptr, MAX_FILE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
base_address = reserved_pages_ptr;
每次调整内存映射大小时,我都会关闭旧文件映射,释放保留的页面并保留当前文件大小不需要的其余页面:
filemapping_handle = CreateFileMappingW(...);
SYSTEM_INFO info;
GetSystemInfo(&info);
const DWORD page_size = info.dwAllocationGranularity;
const DWORD pages_needed = file_size / page_size + size_t(file_size % page_size != 0);
// release reserved pages:
VirtualFree(reserved_pages_ptr, 0, MEM_RELEASE);
// reserve rest pages:
reserved_pages_ptr = (char*)VirtualAlloc(
base_address + pages_needed * page_size,
MAX_FILE_SIZE - pages_needed * page_size,
MEM_RESERVE, PAGE_NOACCESS
);
if(reserved_pages_ptr != base_address + pages_needed * page_size)
{
//I hope this never happens...
}
然后我可以用以下方式映射视图MapViewOfFileEx
:
data_ = (char*)MapViewOfFileEx(filemapping_handle, ... , base_address);
if (data_ != base_address)
{
//I hope this also never happens...
}
这种方法是否足够稳定以保证潜在的问题永远不会发生?我是否需要任何同步来避免多线程问题?
编辑:我知道最稳定的方法是更改应用程序的其余部分以允许使所有文件数据指针无效,但这种解决方案可能是一种反映mmap
Linux 行为的简单方法。