コピーせずにWindowsリングバッファー
-
06-07-2019 - |
解決
私は実際にウィキペディアの例のすべての詳細に従っていませんでした。それを念頭に置いて、 CreateFileMapping を使用して、Windowsのメモリをマップします。 a>および 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 INFORMATIONによって提案されたコードはときどき機能しますが、機能しないこともありますが、とにかく素晴らしいアイデアです。
問題は、 MapViewOfFileEx
がERROR_INVALID_ADDRESSで失敗することがあり、ビューを pBuf + bufferSize
にマップできないことです。これは、前に呼び出された MapViewOfFile
が bufferSize
の長さ( pBuf
から始まる)の空きアドレス空間を選択するが、このアドレスを保証しないためです。 bufferSize * 2
の長さのスペース。そして、なぜ bufferSize * 2
仮想メモリが必要なのでしょうか?リングバッファーをラップする必要があるためです。これが、2番目のマッピングビューの目的です。読み取りまたは書き込みポインターが最初のビューを離れると、(メモリー内で連続しているため)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)