Artigo: 125713 - Última revisão: terça-feira, 21 de Novembro de 2006 - Revisão: 3.1

Ficheiros comuns mapeamento de problemas e diferenças de plataforma

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 | Reduzir tudo

Sumário

Este artigo aborda alguns problemas comuns encontrados quando utilizar o mapeamento do ficheiro. Também aponta fora algumas diferenças de plataforma na implementação de mapeamento do ficheiro.

Este artigo não descreve os procedimentos para efectuar o mapeamento do ficheiro. Para informações sobre como utilizar mapeamento do ficheiro, consulte a descrição geral mapeamento do ficheiro de referência para programadores de Microsoft Win32. Consulte também as descrições CreateFileMapping() OpenFileMapping(), MapViewOfFile(), MapViewOfFileEx(), UnmapViewOfFile() e FlushViewOfFile().

Mais Informação

Conflitos de espaço de nome

Os nomes de eventos, semáforos, exclusão mútua e objectos de mapeamento do ficheiro partilham o mesmo espaço de nome, por isso, não é possível ter dois tipos de objecto diferente com o mesmo nome. É um erro tentar criar ou abrir um objecto de um tipo utilizando um nome que já está a ser utilizado por um objecto de outro tipo.

CreateFileMapping() e OpenFileMapping() irão falhar se um nome de objecto que está a ser utilizado por um objecto de outro tipo especificar. Em ambos os casos, GetLastError() devolverá ERROR_INVALID_HANDLE (6).

Para evitar conflitos entre tipos de objecto, uma solução consiste em incluir o tipo de objecto no nome do. Por exemplo, utilize "EV_myapp_block_ready" para um nome de objecto de evento e "FM_myapp_missile_data" para um ficheiro de mapeamento do nome do objecto.

Necessária do Unmapping todas as vistas de um ficheiro mapeada

O Windows mantém um identificador interno para um objecto de mapeamento de ficheiros para cada vista desse objecto, se criado pelo MapViewOfFile() ou MapViewOfFileEx(). Este identificador interno é mantida para além disso, para o identificador devolvido por CreateFileMapping(). O identificador interno não é fechado até que a vista associada a alça é unmapped por UnmapViewOfFile() chamada. Para completamente fechar um ficheiro mapeamento objecto requer que todos os identificadores para o objecto, incluindo internas alças, ser fechado. Assim, para fechar um objecto de mapeamento do ficheiro, todas as vistas do objecto tem de ser unmapped e o identificador devolvido pelo CreateFileMapping() deve ser fechado.

Extant unmapped vistas de um objecto de mapeamento de ficheiros não fará com que um CloseHandle() numa alça do objecto a falha. Por outras palavras, quando o identificador para o objecto é fechada com êxito, não é necessariamente verdade que todas as vistas tenham sido unmapped, para que o objecto de mapeamento do ficheiro necessariamente não ter sido libertado.

Falha para unmap correctamente todas as vistas do objecto e para fechar o identificador para o objecto fará com que fugas de bloco paginado da aplicação, conjunto não paginado, bytes virtuais e também no sistema bytes larga dedicadas.

Restrições de tamanho do ficheiro de mapeamento de objectos

O tamanho de um objecto de mapeamento do ficheiro pelo ficheiro de paginação do sistema é limitado a memória virtual de sistema disponíveis (ou seja, a quantidade de memória que pode ser consolidada através de uma chamada para VirtualAlloc()).

No Windows NT, o tamanho de um objecto de mapeamento de ficheiro por um ficheiro de disco com o nome está limitado pelo espaço em disco disponível. O tamanho de uma vista mapeada de um objecto é limitado ao maior bloco contíguo de memória virtual não reservado no processo de efectuar o mapeamento (no máximo, 2 GB menos a memória virtual já reservada pelo processo).

No Win32s, o tamanho de um objecto de mapeamento de ficheiro por um ficheiro de disco com o nome está limitado a memória virtual de sistema disponíveis, devido à implementação do Win32s gestão de memória virtual. Win32s atribui memória virtual normal para a memória secção mapeada, apesar de não necessita de espaço de comutação e o valor da VM definido pelo Windows é demasiado pequena para mapear ficheiros grandes. 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 objecto de mapeamento de ficheiro por um ficheiro de disco com o nome está limitado a espaço em disco disponível. O tamanho de uma vista mapeada de um objecto é limitado ao maior bloco contíguo de memória virtual não reservado arena o partilhada virtual. Este bloco será até 1 GB, menos qualquer memória em utilização por outros componentes do Windows 95 que utilizam a arena virtual partilhada (tais como aplicações de 16 bits baseado no Windows). Cada vista mapeada utilizam memória a partir deste arena para que este limite aplica-se ao tamanho total de todas as sem as sobrepor mapeadas vistas para todas as aplicações em execução no sistema.

Mapeada ficheiro pode não ser aumentado automaticamente

Se o tamanho especificado para um objecto de mapeamento do ficheiro de segurança por um disco designado ficheiro numa chamada para CreateFileMapping() é maior do que o tamanho do ficheiro utilizado para efectuar o mapeamento de segurança, o ficheiro normalmente será aumentado para o tamanho especificado pela chamada CreateFileMapping().

Apenas Windows NT, se PAGE_WRITECOPY for especificado no parâmetro fdwProtect, o ficheiro será não automaticamente ser aumentado. Isto provocará CreateFileMapping() falhar e GetLastError() devolverá ERROR_NOT_ENOUGH_MEMORY (8). Para definir o tamanho do ficheiro antes de chamar CreateFileMapping(), utilize SetFilePointer() e SetEndOfFile().

MapViewOfFileEx() e o intervalo válido de lpvBase

No Windows NT, vistas de objectos de mapeamento do ficheiro são mapeadas no intervalo de endereços de 0-2 GB. Passar um endereço fora deste intervalo como o lpvBase parâmetro para MapViewOfFileEx() fará com que este falhe e GetLastError() devolverá ERROR_INVALID_PARAMETER (87 valores).

No Windows 95, vistas de objectos de mapeamento de ficheiros são mapeadas intervalo de endereços de 2-3 GB (a arena virtual partilhada). Passar um endereço fora deste intervalo provocará MapViewOfFileEx() falhar e GetLastError() devolverá ERROR_INVALID_ADDRESS (487). Nota que futuras actualizações para o Windows 95 podem alterar o intervalo de mapeamento para 0-2 GB, como no Windows NT.

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

Se for especificado um endereço para o parâmetro lpvBase MapViewOfFileEx() e, não existe um bloco de espaço de endereço virtual não reservados nesse endereço suficiente para satisfazer o número de bytes especificado no parâmetro cbMap, MapViewOfFileEx() falhará e GetLastError() devolverá ERROR_NOT_ENOUGH_MEMORY (8). Isto não significa que o sistema está com pouca memória ou que o processo não é possível atribuir mais memória. Significa simplesmente que o intervalo de endereço virtual pedido já foi reservado nesse processo.

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

MapViewOfFileEx() e granularidade de lpvBase

Para o parâmetro lpvBase especificado numa chamada para MapViewOfFileEx(), deverá utilizar um múltiplo integral do granularidade de alocação do sistema. No Windows NT, não especificar um valor tal fará com que MapViewOfFileEx() falhas e GetLastError() devolver ERROR_MAPPED_ALIGNMENT (1132). No Windows 95, o endereço será arredondado para o múltiplo mais próximo integral de granularidade de alocação do sistema.

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

Endereços de vistas mapeadas

Ao mapear uma vista de um ficheiro (ou de memória partilhada), é possível ou permitir que o sistema operativo determinar o endereço da vista ou para especificar um endereço como parâmetro da função MapViewOfFileEx() lpvBase. Se o mapeamento do ficheiro vai ser partilhadas por vários processos, em seguida, o método recomendado é utilizar MapViewOfFile() e deixar o sistema operativo, seleccione o endereço de mapeamento para a. Existem bons motivos para o fazer:
  • No Windows NT, vistas são mapeadas independentemente para espaço de endereços cada processo. Embora possa ser conveniente tentar mapear a vista no mesmo endereço em cada processo, o intervalo de endereços virtual especificado pode não estar disponível em todos os processos envolvidos. Por conseguinte, o mapeamento poderia falhar de uma (ou mais) dos processos tentar partilhar o mapeamento do ficheiro.
  • No Windows 95, o mapeamento do ficheiro objectos existe na 2 - 3 GB endereço intervalo (a arena virtual partilhado). Por conseguinte, depois do endereço inicial para a vista for determinado, vistas adicionais do mapeamento de serão mapeadas para o mesmo endereço em cada processo na mesma, e não existe nenhuma vantagem em tentar forçar o mapeamento inicial para um endereço específico. Para as vistas segunda e subsequentes de um objecto de mapeamento, se o endereço especificado para lpvBase não corresponde ao endereço real onde Windows 95 tiver mapeado a vista, em seguida, MapViewOfFileEx() falhar e GetLastError() devolve ERROR_INVALID_ADDRESS (487). Além disso, quando tenta ligar a primeira vista num endereço pre-determined, esse endereço já deve estar em utilização por outros componentes do Windows 95 que utilizam a arena virtual partilhada. Nota que futuras actualizações para o Windows 95 podem alterar o intervalo de mapeamento para 0-2 GB, como no Windows NT.
Se for absolutamente necessário para criar os mapeamentos no mesmo endereço nos vários processos em Windows NT, Eis duas abordagens possíveis:
  1. Escolha um endereço adequados e gerir o espaço de endereçamento virtual para que este endereço fica disponível. Isto significa basear as DLLs, atribuição de memória em localizações específicas e utilizar uma ferramenta como o processo Walker para observar o padrão de espaço de endereçamento virtual. Assim que possível na execução da aplicação, reservar o espaço de endereço pretendido ou executar o mapeamento. Um bom local para efectuar este procedimento é no processamento PROCESS_ATTACH na DLL, porque é chamado antes do executável propriamente dito é iniciado. NOTA: é ainda não garante que algumas DLL irá não tenha já carregado no endereço em questão. Se não consegue mapear todos os processos envolvidos no endereço predeterminado, podem falhar ou tente um novo endereço.

    - ou -
  2. Tem todos os processos envolvidos negociar um endereço adequado. Os processos podem todos utilizar a função VirtualQuery() para verificar os respectivos espaços de endereços até um endereço comum é encontrado em cada processo que tem uma grande suficiente bloco não reservado. Isto requer que todos os processos envolvidos mapear o endereço ao mesmo tempo. Um processo iniciado depois do endereço foi determinado deve mapear esse endereço e falhar se este não é possível fazê-lo. Em alternativa, o processo de negociação pode ser repetido, com cada remapeamento de processo no novo endereço. Em seguida, tem de ser readjusted todos os ponteiros para o mapeamento.
O segundo método é mais provável que tenha êxito. Também pode ser combinado com o primeiro para o tornar mais provável que um endereço adequado vai encontrar rapidamente.

Quando as vistas são mapeadas para endereços diferentes no Windows NT, a dificuldade que resulta é armazenar apontadores para o mapeamento no mapeamento propriamente dito. Isto acontece porque um ponteiro de um processo não aponta para a localização do mesma no mapeamento em outro processo. Para ultrapassar este problema, armazenar desvios em vez de ponteiros do mapeamento e calcular endereços reais em cada processo, adicionando o endereço base do mapeamento do deslocamento. Também é possível utilizados ponteiros com base e assim executar a base + desfasamento conversão implicitamente. Um exemplo SDK curto chamado BPOINTER demonstra esta técnica.

Diferenças de plataforma adicionais

Limitações adicionais durante a execução do ficheiro mapeamento no Windows 95:
  1. Os parâmetros de dwOffsetHigh MapViewOfFile() e MapViewOfFileEx() não são utilizados e devem ser zero. O Windows 95 utiliza um sistema de ficheiros 32 bits.
  2. O parâmetro dwMaximumSizeHigh CreateFileMapping() não é utilizado e deve ser zero. Novamente, isto deve-o sistema de ficheiros de 32 bits.
  3. Os sinalizadores SEC_IMAGE e SEC_NOCACHE para o parâmetro fdwProtect CreateFileMapping() não são suportados.
  4. Se o sinalizador FILE_MAP_COPY é utilizado para mapear uma vista de um objecto de mapeamento do ficheiro, o objecto deve ter sido criado utilizando PAGE_WRITECOPY protecção. Além disso, o objecto deve ser efectuado através de um ficheiro com nome em vez do ficheiro de paginação do sistema (por outras palavras, um ficheiro válido processar, não (identificador) 0xFFFFFFFF, deve ser especificada para o parâmetro hFile de CreateFileMapping()). Não o fizer qualquer um destes faz com que MapViewOfFile() falhas e GetLastError() devolver ERROR_INVALID_PARAMETER (87 valores).
  5. Se dois ou mais processos mapear uma vista PAGE_WRITECOPY do mesmo objecto de mapeamento do ficheiro (utilizando um objecto com nome, por exemplo), são para ver as alterações efectuadas à vista por outros process(es). O ficheiro de disco real não será modificado, no entanto. No Windows NT, se um processo escreve para a vista, recebe a sua própria cópia das páginas modificadas e não irá afectar as páginas outros process(es) ou o ficheiro de disco.

A informação contida neste artigo aplica-se a:
  • Microsoft Win32 Application Programming Interface 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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/ )