我并没有完全理解维基百科示例的所有细节。考虑到这一点,你可以使用 CreateFileMapping 和 MapViewOfFile 在 Windows 中映射内存,但是 MapViewOfFile 不允许您指定映射的基地址。 可以使用 MapViewOfFileEx 来指定基地址,因此您可以使用类似的技术。
我无法确定这是否真的有效:
// determine valid buffer size
SYSTEM_INFO info;
GetSystemInfo(&info);
// note that the base address must be a multiple of the allocation granularity
DWORD bufferSize=info.dwAllocationGranularity;
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
bufferSize*2,
L"Mapping");
BYTE *pBuf = (BYTE*)MapViewOfFile(hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
bufferSize);
MapViewOfFileEx(hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
bufferSize,
pBuf+bufferSize);
嘿,这是最近一直困扰我的话题。我需要在Windows上使用posix优化的环形缓冲区,主要是因为其随机访问接口,但我从来没有想过如何实现它。现在,@1800 INFORMATION提出的代码有时有效,有时无效,但该想法仍然很好。
问题在于MapViewOfFileEx
有时会失败并显示ERROR_INVALID_ADDRESS,这意味着它无法将视图映射到pBuf+bufferSize
。这是因为之前调用的MapViewOfFile
选择了一个长度为bufferSize
的自由地址空间(从pBuf
开始),但它并不保证这个地址空间也有bufferSize*2
那么长。我们为什么需要bufferSize*2
虚拟内存?因为我们的环形缓冲区需要回绕。这就是第二个映射视图的作用。当读写指针离开第一个视图时,它进入第二个视图(因为它们在内存中是连续的),但实际上它重新从同一个映射开始。
UINT_PTR addr;
HANDLE hMapFile;
LPVOID address, address2;
hMapFile = CreateFileMapping ( // create a mapping backed by a pagefile
INVALID_HANDLE_VALUE,
NULL,
PAGE_EXECUTE_READWRITE,
0,
bufferSize*2,
"Local\\mapping" );
if(hMapFile == NULL)
FAIL(CreateFileMapping);
address = MapViewOfFile ( // find a free bufferSize*2 address space
hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
bufferSize*2 );
if(address==NULL)
FAIL(MapViewOfFile);
UnmapViewOfFile(address);
// found it. hopefully it'll remain free while we map to it
addr = ((UINT_PTR)address);
address = MapViewOfFileEx (
hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
bufferSize,
(LPVOID)addr );
addr = ((UINT_PTR)address) + bufferSize;
address2 = MapViewOfFileEx (
hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
bufferSize,
(LPVOID)addr);
if(address2==NULL)
FAIL(MapViewOfFileEx);
// when you're done with your ring buffer, call UnmapViewOfFile for
// address and address2 and CloseHandle(hMapFile)
VirtualAlloc
来修复,然后使用两个调用MapViewOfFileEx
将VirtualAlloc
找到的单个地址范围的两个半部分传递进去。 - Ben Voigt