문제

링 버퍼의 위키 백과 항목, 거기 있습니다 예제 코드 해킹을 보여줍니다 유닉스 메모리에 인접한 가상 메모리가 매핑 동일한 phbycical 메모리에 memcpy, 등. ?

감사합니다, 프레이저

도움이 되었습니까?

해결책

나는 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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top