Pergunta

Sobre Entrada da Wikipedia do Buffer de anel, há código de exemplo mostrando um hack para Unix sistemas pelos quais a memória virtual adjacente para uma peça de memória é mapeado para a mesma memória phbysical, implementando assim um buffer de anel sem a necessidade de qualquer memcpy, etc. Eu estava me perguntando se há uma maneira de ser algo semelhante em janelas?

Obrigado, Fraser

Foi útil?

Solução

Eu realmente não segui todos os detalhes do exemplo na Wikipedia. Com isso em mente, você mapeia a memória no Windows usando Createfilemapping e MapViewOffile, no entanto, o MapViewOffile não permite especificar um endereço base para o mapeamento. MapViewOffileEx Pode ser usado para especificar um endereço base, para que você possa usar uma técnica semelhante.

Não tenho nenhuma maneira de dizer se isso realmente funcionaria:

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

Outras dicas

Oh, ei, este é o tópico que me preocupou muito ultimamente. Eu precisava de buffer de anel otimizado para Posix no Windows, principalmente por causa de sua interface de acesso aleatório, mas nunca tive nenhuma idéia de como implementá-lo. Agora, o código proposto por @1800 informações funciona às vezes, às vezes não, mas a ideia é ótima de qualquer maneira.

A coisa é, MapViewOfFileEx às vezes falha com error_invalid_address, o que significa que ele não pode mapear a visualização para pBuf+bufferSize. Isso é porque o MapViewOfFile chamado antes de selecionar um espaço de endereço gratuito de bufferSize comprimento (começando de pBuf), mas não é garra este espaço de endereço para ser bufferSize*2 grandes. E por que precisaríamos bufferSize*2 memória virtual? Porque nosso buffer de anel precisa envolver. É para isso que serve a segunda visão de mapeamento. Quando o ponteiro de leitura ou gravação deixa a primeira visão, ele entra na segunda visão (porque eles são contigiosos na memória), mas na verdade ele começa com o mesmo mapeamento.

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top