ID do artigo: 125713 - Última revisão: terça-feira, 21 de novembro de 2006 - Revisão: 3.1

Mapeamento problemas e plataforma diferenças de arquivo comuns

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sumário

Este artigo aborda alguns problemas comuns encontrados ao usar o mapeamento do arquivo. Ele também aponta algumas diferenças de plataforma na implementação de mapeamento de arquivo.

Este artigo não descreve os procedimentos para executar o mapeamento do arquivo. Para obter informações sobre como usar mapeamento de arquivo, consulte Visão geral de mapeamento de arquivo na referência do programador do Microsoft Win32. Consulte também as descrições para CreateFileMapping(), OpenFileMapping(), MapViewOfFile(), MapViewOfFileEx(), UnmapViewOfFile() e FlushViewOfFile().

Mais Informações

Conflitos de espaço de nome

Os nomes de eventos, semáforo, mutex e objetos de mapeamento de arquivo compartilham o mesmo espaço para nome, portanto, não é possível ter dois tipos de objeto diferente com o mesmo nome. Ele é um erro para tentar criar ou abrir um objeto de um tipo usando um nome que já está sendo usado por um objeto de outro tipo.

CreateFileMapping() e OpenFileMapping() irá falhar se eles especificar um nome de objeto que está em uso por um objeto de outro tipo. Em ambos os casos, GetLastError() retornará ERROR_INVALID_HANDLE (6).

Para evitar conflitos entre tipos de objeto, uma solução é incluir o tipo de objeto no nome. Por exemplo, use "EV_myapp_block_ready" para um nome de objeto de evento e "FM_myapp_missile_data" para um arquivo de mapeamento de nome do objeto.

Necessidade de Unmapping todos os modos de um arquivo mapeada

O Windows mantém um identificador interno para um objeto de mapeamento de arquivo para cada modo de exibição do objeto, se criado pelo MapViewOfFile() ou MapViewOfFileEx(). O identificador interno é mantido além para o identificador retornado por CreateFileMapping(). O identificador interno não é fechado até que a exibição associada com o identificador é desmapeada por chamada UnmapViewOfFile(). Para fechar completamente um arquivo de mapeamento de objeto requer que todos os identificadores para o objeto, incluindo internas alças, ser fechado. Portanto, para fechar um objeto de mapeamento de arquivo, todos os modos do objeto devem ser não mapeados, e o identificador retornado por CreateFileMapping() deve ser fechado.

Empacotamentos modos de exibição não mapeados de um objeto de mapeamento de arquivo não fará com que um CloseHandle() alça do objeto falhe. Em outras palavras, quando o identificador para o objeto é fechado com êxito, não é necessariamente verdadeiro se todos os modos de exibição foram não mapeados, para que o objeto de mapeamento de arquivo necessariamente não tinha sido liberado.

Falha para desmapeamento corretamente todos os modos do objeto e para fechar o identificador para o objeto fará com que vazamentos no pool paginado do aplicativo, não-paginável, bytes virtuais e também no sistema de bytes confirmados largo.

Restrições sobre o tamanho dos objetos de mapeamento de arquivo

O tamanho de um objeto de mapeamento de arquivo feito pelo arquivo de paginação do sistema é limitado a memória virtual de sistema disponíveis (ou seja, a quantidade de memória que pode ser confirmada com uma chamada para VirtualAlloc()).

No Windows NT, o tamanho de um objeto de mapeamento de arquivo feito por um arquivo nomeado disco é limitado pelo espaço em disco disponível. O tamanho de uma exibição mapeada de um objeto é limitado ao maior bloco contíguo de memória virtual não reservada no processo de executar o mapeamento (no máximo, 2 GB menos a memória virtual já está reservada pelo processo).

Em Win32s, o tamanho de um objeto de mapeamento de arquivo feito por um arquivo nomeado disco é limitado a memória virtual disponível no sistema, devido à implementação do gerenciamento de memória virtual do Win32s. Win32s aloca regular memória virtual para a seção mapeada mesmo que não é necessário espaço de permuta, e a quantidade de VM definido pelo Windows é muito pequena para usar para mapeamento de arquivos grandes de memória. Como com o Windows NT, espaço em disco disponível também irá impor uma limitação.

No Windows 95, o tamanho de um objeto de mapeamento de arquivo feito por um arquivo nomeado disco é limitado a espaço em disco disponível. O tamanho de uma exibição mapeada de um objeto é limitado para o maior bloco contíguo de memória virtual não reservada em arena do virtual compartilhado. Este bloco será no máximo 1 GB, menos qualquer memória em uso por outros componentes do Windows 95 que usar arena do virtual compartilhado (como aplicativos baseados no Windows de 16 bits). Cada modo de exibição mapeado usarão memória deste arena, para que esse limite se aplica ao tamanho total de todos os não-sobreposição mapeados modos para todos os aplicativos em execução no sistema.

Mapeada arquivo pode não ser automaticamente crescimento

Se o tamanho especificado para um objeto de mapeamento de arquivo feito por um disco chamado arquivo em uma chamada para CreateFileMapping() é maior que o tamanho do arquivo usado para fazer o mapeamento, o arquivo normalmente será expandido para o tamanho especificado pela chamada CreateFileMapping().

No Windows NT somente, se PAGE_WRITECOPY for especificado para o parâmetro fdwProtect, o arquivo será não automaticamente ser crescimento. Isso fará com que CreateFileMapping() falhar e GetLastError() retornará ERROR_NOT_ENOUGH_MEMORY (8). Para definir o tamanho do arquivo antes de chamar CreateFileMapping(), use SetFilePointer() e SetEndOfFile().

Intervalo válido de lpvBase e MapViewOfFileEx()

No Windows NT, modos de exibição de objetos de mapeamento de arquivo são mapeados no intervalo de endereço de 0-2 GB. Passando um endereço fora desse intervalo como o lpvBase parâmetro para MapViewOfFileEx() fará com que ele falhar e GetLastError() retornará ERROR_INVALID_PARAMETER (87).

No Windows 95, modos de exibição de objetos de mapeamento de arquivo são mapeados no intervalo de endereço de 2-3 GB (compartilhado virtual arena do). Passar um endereço fora desse intervalo fará com que MapViewOfFileEx() falhar e GetLastError() retornará ERROR_INVALID_ADDRESS (487). Observe que atualizações futuras do Windows 95 podem alterar o intervalo de mapeamento para 0-2 GB, como no Windows NT.

MapViewOfFileEx() e status de alocação de lpvBase

Se um endereço for especificado para parâmetro de MapViewOfFileEx() lpvBase e não há um bloco de espaço de endereço virtual não reservada nesse endereço grande o suficiente para satisfazer o número de bytes especificado no parâmetro cbMap, em seguida, MapViewOfFileEx() falhará e GetLastError() retornará ERROR_NOT_ENOUGH_MEMORY (8). Isso não significa que o sistema está com pouca memória ou que o processo não é possível alocar mais memória. Isso simplesmente significa que o intervalo de endereços virtuais solicitado já foi reservado nesse processo.

Antes chamada MapViewOfFileEx(), VirtualQuery() pode ser usado para determinar um intervalo adequado do espaço de endereço virtual não reservada.

MapViewOfFileEx() e granularidade de lpvBase

Para o parâmetro lpvBase especificado em uma chamada para MapViewOfFileEx(), você deve usar um múltiplo de granularidade de alocação do sistema. No Windows NT, não especificar um valor tão fará com que MapViewOfFileEx() falha e GetLastError() retornar ERROR_MAPPED_ALIGNMENT (1132). No Windows 95, o endereço será arredondado para baixo para o múltiplo mais próximo integral de granularidade de alocação do sistema.

Para determinar a granularidade de alocação do sistema, chame GetSystemInfo().

Endereços dos modos de exibição mapeados

Ao mapear uma exibição de um arquivo (ou memória compartilhada), é possível ou permitir que o sistema operacional determinar o endereço do modo de exibição, ou para especificar um endereço como parâmetro de função MapViewOfFileEx() lpvBase. Se o mapeamento do arquivo a ser compartilhada entre vários processos, em seguida, o método recomendado é usar MapViewOfFile() e deixar que o sistema operacional selecione o endereço do mapeamento para você. Há bons motivos para isso:
  • No Windows NT, modos de exibição são mapeados independentemente para espaço de endereço do cada processo. Embora talvez seja conveniente tentar mapear o modo de exibição no mesmo endereço em cada processo, o intervalo de endereços virtual especificado não pode ser gratuito em todos os processos envolvidos. Portanto, o mapeamento pode falhar em um (ou mais) dos processos tentando compartilhar o mapeamento do arquivo.
  • No Windows 95, mapeamento de arquivo objetos consta 2 - 3 GB endereço intervalo (a arena virtual compartilhado). Portanto, uma vez determinado o endereço inicial para o modo de exibição, exibições adicionais do mapeamento serão mapeadas para o mesmo endereço em cada processo assim mesmo, e não há nenhum benefício na tentativa de forçar o mapeamento inicial para um endereço específico. Para as exibições segundos e subseqüentes de um objeto de mapeamento, se o endereço especificado para lpvBase não corresponde ao endereço real onde Windows 95 tiver mapeado o modo de exibição, em seguida, MapViewOfFileEx() falhar e GetLastError() retorna ERROR_INVALID_ADDRESS (487). Além disso, ao tentar mapear a primeira exibição em um endereço predeterminado, esse endereço já pode estar em uso por outros componentes do Windows 95 que usar arena do virtual compartilhado. Observe que atualizações futuras do Windows 95 podem alterar o intervalo de mapeamento para 0-2 GB, como no Windows NT.
Se for absolutamente necessário criar os mapeamentos no mesmo endereço em vários processos em Windows NT, aqui estão duas abordagens possíveis:
  1. Escolha um endereço apropriado e gerenciar o espaço de endereço virtual para que este endereço fique disponível. Isso significa que basear suas DLLs, alocação de memória em locais específicos e usando uma ferramenta como o processo Walker para observar o padrão de espaço de endereço virtual. Tão logo seja possível na execução do aplicativo, reservar o espaço de endereço desejado ou executar o mapeamento. Um bom lugar para isso é no tratamento PROCESS_ATTACH em uma DLL, porque ele é chamado antes que o executável propriamente dito é iniciado. Observação: Há ainda sem garantia de que alguns DLL serão não já tiver carregado no endereço em questão. Se não podem mapear todos os processos envolvidos no endereço predeterminado, eles podem falhar ou tente um novo endereço.

    - ou -
  2. Ter todos os processos envolvidos negociar um endereço apropriado. Os processos podem todos usar a função VirtualQuery() para verificar seus espaços de endereço até que um endereço comum é encontrado em cada processo que tem uma grande suficiente bloco não reservado. Isso requer que todos os processos envolvidos mapeiam o endereço ao mesmo tempo. Um processo que inicia depois que o endereço foi determinado deve mapear nesse endereço e falhar se ele não pode fazer isso. Como alternativa, o processo de negociação pode ser repetido, com cada processo remapeamento no novo endereço. Em seguida, todos os ponteiros para o mapeamento devem ser reajustados.
O segundo método é muito mais provável que seja bem-sucedida. Também podem ser combinada com a primeira para torná-lo mais provável que um endereço apropriado será encontrado rapidamente.

Quando os modos de exibição são mapeados para endereços diferentes no Windows NT, a dificuldade surge está armazenando ponteiros para o mapeamento no mapeamento propriamente dito. Isso ocorre porque um ponteiro em um processo não aponta para o mesmo local dentro o mapeamento em outro processo. Para superar esse problema, armazenar deslocamentos em vez de ponteiros no mapeamento e calcular endereços reais em cada processo adicionando o endereço base do mapeamento para o deslocamento. Ele também é possível ponteiros usados com base e, portanto, executar a base + deslocamento conversão implicitamente. Uma pequena amostra do SDK chamada BPOINTER demonstra essa técnica.

Diferenças adicionais de plataforma

Limitações adicionais ao executar arquivo de mapeamento em Windows 95:
  1. Os parâmetros dwOffsetHigh do MapViewOfFile() e MapViewOfFileEx() não são usados e devem ser zero. O Windows 95 usa um sistema de arquivos 32 bits.
  2. Parâmetro de CreateFileMapping() dwMaximumSizeHigh não é usado e deve ser zero. Novamente, isso é devido ao sistema de arquivos de 32 bits.
  3. Não há suporte para os sinalizadores SEC_IMAGE e SEC_NOCACHE para o parâmetro fdwProtect de CreateFileMapping().
  4. Se o sinalizador FILE_MAP_COPY é usado para mapear uma exibição de um objeto de mapeamento de arquivo, o objeto deve ter sido criado usando PAGE_WRITECOPY proteção. Além disso, o objeto deve ser feito por um arquivo nomeado em vez do arquivo de paginação do sistema (em outras palavras, um arquivo válido manipular, não (HANDLE) 0xFFFFFFFF, deve ser especificado para parâmetro de CreateFileMapping()) hFile. Falha ao fazer um deles faz com que MapViewOfFile() para falhas e GetLastError() retornar ERROR_INVALID_PARAMETER (87).
  5. Se dois ou mais processos mapear uma exibição PAGE_WRITECOPY do mesmo objeto de mapeamento de arquivo (usando um objeto nomeado, por exemplo), eles são capazes de ver as alterações feitas para o modo de exibição por outros processos. O arquivo de disco real não é modificado, no entanto. No Windows NT, se um processo grava para o modo de exibição, ele recebe sua própria cópia de páginas modificadas e não afetará as páginas de outros processos ou o arquivo de disco.

A informação contida neste artigo aplica-se a:
  • Interface de Programação de Aplicativos do Microsoft Win32 nas seguintes plataformas
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows 95
    • Microsoft Win32s 1.3
Palavras-chave: 
kbmt KB125713 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 125713  (http://support.microsoft.com/kb/125713/en-us/ )