Windows环形缓冲区不复制

在Ring Buffer的维基百科条目中 ,有一些示例代码显示了UNIX系统的黑客攻击,其中一个内存的相邻虚拟内存被映射到相同的物理内存,从而实现了环形缓冲区,而不需要任何memcpy等。如果有一种方式在Windows中类似的东西?

谢谢,弗雷泽

Solutions Collecting From Web of "Windows环形缓冲区不复制"

我没有真正按照wikipedia中的例子的所有细节。 考虑到这一点,您可以使用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信息提供的代码有时是有效的,有时候不是,但是这个想法是好的。

问题是, MapViewOfFileEx有时会失败,ERROR_INVALID_ADDRESS意味着它不能将视图映射到pBuf+bufferSize 。 这是因为之前调用的MapViewOfFile选择了bufferSize长度的空闲地址空间(从pBuf开始),但是不保证这个地址空间是bufferSize*2 long。 为什么我们需要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)