복사하지 않고 Windows 링 버퍼
-
06-07-2019 - |
해결책
나는 Wikipedia의 예제의 모든 세부 사항을 실제로 따르지 않았습니다. 이를 염두에두고 CreateEfilemapping 그리고 MapViewoffile, 그러나 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
긴. 그리고 왜 우리에게 필요한가? 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)