Frage

An Wikipedia -Eintrag von Ringpuffer, es gibt es Beispielcode einen Hack für zeigen Unix Systeme, bei denen der angrenzende virtuelle Speicher an ein Stück Speicher ist zugeordnet zum gleichen phbysikalischen Speicher, wodurch ein Ringpuffer implementiert wird, ohne dass es nach Bedarf erforderlich ist memcpy, usw. Ich habe mich gefragt, ob es einen Weg gibt, um so etwas Ähnliches in Fenster?

Danke, Fraser

War es hilfreich?

Lösung

Ich habe nicht wirklich alle Details des Beispiels in Wikipedia gefolgt. In diesem Sinne kartieren Sie Speicher in Windows mit verwenden CreateFilemapping und MapViewoffile, Mit MapViewoffile können Sie jedoch nicht eine Basisadresse für die Zuordnung angeben. MapViewOfIFILEEx Kann verwendet werden, um eine Basisadresse anzugeben, sodass Sie möglicherweise eine ähnliche Technik verwenden können.

Ich habe keine Möglichkeit zu sagen, ob dies tatsächlich funktionieren würde:

// 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);

Andere Tipps

Oh hey, das ist das Thema, das mich in letzter Zeit sehr beunruhigt hat. Ich brauchte einen posix-optimierten Ringpuffer unter Windows, hauptsächlich wegen seiner zufälligen Zugriffsoberfläche, hatte aber nie eine Idee, wie sie es implementieren sollte. Jetzt funktioniert der von @1800 Informationen vorgeschlagene Code manchmal manchmal, manchmal nicht, aber die Idee ist ohnehin großartig.

Die Sache ist, MapViewOfFileEx fällt manchmal mit error_invalid_address aus, was bedeutet, dass es die Ansicht nicht zuordnen kann pBuf+bufferSize. Das liegt daran, dass die MapViewOfFile Angerufen zuvor wählt ein kostenloser Adressraum von aus bufferSize Länge (beginnend von pBuf), aber es garantiert diesen Adressraum nicht zu sein bufferSize*2 lang. Und warum sollten wir brauchen bufferSize*2 virtueller Speicher? Weil unser Ringpuffer einwickeln muss. Dafür ist die zweite Mapping -Ansicht da. Wenn der Lese- oder Schreibzeiger die erste Ansicht verlässt, tritt er in die zweite Ansicht ein (weil er in Erinnerung anwesend ist), aber tatsächlich beginnt er bei derselben Zuordnung von vorhanden.

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top