Como saber se um arquivo está mapeado na memória?

6

Eu estou confuso sobre os arquivos mapeados na memória, então eu tenho algumas perguntas que eu ficaria muito feliz se você pudesse me ajudar.

  1. Digamos que eu procure um diretório no meu sistema de arquivos e haja um arquivo nesse diretório. É possível que esse arquivo aponte para uma região na memória principal, em vez de apontar para uma região no disco?
  2. Se isso for possível, isso é o que chamamos de 'arquivo mapeado por memória'?
  3. Qual seria o significado de mover esse arquivo pelo sistema de arquivos (ou seja, mv ing tal arquivo de um diretório para outro)? O que entendo é que, como o arquivo é mapeado pela memória, o (s) processo (s) interagindo com o arquivo sempre grava em uma região predefinida da memória principal e, quando abrimos esse arquivo (por exemplo, usando vim ), lemos que região da memória principal (portanto, nenhum disco está envolvido). Portanto, não importa onde nós movemos o arquivo, ele sempre funcionará corretamente, certo? Se sim, mover o arquivo pelo sistema de arquivos tem algum significado?
  4. Existe um comando que informaria se um arquivo está mapeado na memória?
  5. Finalmente, se eu abrir um arquivo mapeado na memória com vim , faça algumas alterações nele e salve e feche vim , o que acontecerá? As minhas alterações serão simplesmente gravadas na memória principal? Se for esse o caso, outros processos que usam esse arquivo verão as alterações que acabei de fazer? Na minha experiência, os outros processos não viram as alterações que fiz no arquivo quando fiz algumas alterações no arquivo com vim . Qual é o motivo disso?
por Utku 13.09.2016 / 10:34

4 respostas

23

Arquivos mapeados na memória funcionam ao contrário. O mapeamento de memória não é uma propriedade do arquivo, mas uma maneira de acessar o arquivo: um processo pode mapear o conteúdo de um arquivo (ou um subconjunto dele) em seu espaço de endereço. Isso facilita a leitura e gravação no arquivo; fazer isso envolve simplesmente ler e escrever na memória. O arquivo em si, no disco, é o mesmo que qualquer outro arquivo.

Para configurar isso, os processos usam a função mmap . Isso também pode ser usado para outros fins, como compartilhamento de memória entre processos.

    
por 13.09.2016 / 10:39
10

Um arquivo mapeado na memória não é (necessariamente) suportado pela memória. Pode perfeitamente viver em um disco. Na verdade, onde um arquivo reside não é uma propriedade do arquivo em si, mas do sistema de arquivos em que ele reside.

Mapear um arquivo na memória é uma operação que um processo pode fazer para ter uma parte do arquivo carregada na memória. O resultado se parece com uma região regular de memória, exceto que, quando o processo lê ou grava nessa região, ele realmente lê e grava no arquivo. Se você abrir um arquivo, mapeá-lo para a memória, escrever para ele e salvá-lo, a modificação será feita no arquivo, no disco (se ele estiver em um disco, é claro).

Isso pode ser usado, por exemplo, quando você sabe que tem muitos acessos para fazer em um arquivo, que não serão sequenciais, porque pode ser mais fácil e mais eficiente fazer leituras e gravações na memória do que emitir read , write e llseek chamadas do sistema. O único problema com este método é que você não pode realmente usá-lo se o arquivo precisar ser lido ou gravado por vários processos simultaneamente. Os resultados seriam imprevisíveis.

Não conheço nenhum comando que possa dizer se um arquivo está mapeado no momento. Você pode inspecionar os mapeamentos de um processo, no entanto, em /proc/<pid>/maps (se o seu sistema tiver).

Para responder sua segunda pergunta, quando você abre um arquivo, mesmo se você movê-lo no sistema de arquivos, os processos que o abriram ainda podem usá-lo. O que acontece é que um arquivo não é dependente de suas entradas nos sistemas de arquivos. Contanto que você tenha um arquivo aberto, você tem um "identificador", um descritor de arquivo, que permite ler e gravar nele, mesmo que seu caminho no sistema de arquivos seja alterado. Um arquivo desaparece apenas quando não tem entrada no sistema de arquivos e nenhum processo contém um descritor de arquivo.

    
por 13.09.2016 / 10:50
9

Q4: Is there a command which would tell if a file is memory-mapped?

O comando lsof mostrará todos os arquivos atualmente em uso pelo sistema. A coluna "FD" conterá "mem" se o arquivo estiver mapeado na memória. Assim, você pode usar a saída desse comando para o nome de arquivo em que está interessado.

    
por 13.09.2016 / 12:59
7

Você parece confundir o mapeamento de memória com arquivos em memória residentes sistemas de arquivos, juntamente com outros conceitos como como os processos mantêm o acesso a arquivos, mesmo quando eles são movidos ao redor.

Vou fazer perguntas por pergunta para ver se consigo esclarecer as coisas.

  1. Let's say I browse to a directory in my file system and there is a file in this directory. Is it possible that this file points to a region in the main memory, instead of pointing to a region in the disk?

Aponta para a memória principal se estiver em um sistema de arquivos residindo na memória, como procfs que normalmente é montado em / proc, ou sysfs que está em / sys, ou tmpfs que às vezes está em / tmp.

  1. If this is possible, is this what we call 'memory-mapped file'?

Não. Como stephen-kitt disse, "mapeamento de memória" refere-se a uma maneira de acessar um arquivo por "mapear" na memória principal e trabalhar com ela em vez de ler e ler escrevendo pedaços de cada vez através de funções como read () e write ().

  1. What would be the meaning of moving such file around the file system (that is, mving such file from a directory into another)? What I understand is, since the file is memory mapped, the process(es) interacting with the file always writes to a predefined region of the main memory, and when we open that file (for example using vim), we read that region of main memory (so, no disk is involved). Hence, no matter where we move the file, it will always work correctly right? If yes, does moving the file around the file system has any significance?

Se você movê-lo dentro do mesmo sistema de arquivos, você está apenas se movendo em torno de uma referência, um inode de um diretório para outro. Se houver programas que já tinham este arquivo aberto, eles ainda estarão acessando o mesmo arquivo porque eles já têm o inode na mão através de um descritor de arquivo. Isto é o que aconteceu com o arquivo table_name.idb que você mencionou em um comentário.

  1. Is there a command which would tell if a file is memory-mapped?

Wossname já respondeu isso para arquivos mapeados na memória. lsof dirá a você quais processos têm o arquivo mapeado na memória.

Para saber se um arquivo está em um sistema de arquivos que reside na memória, você pode usar df ou mount para listar os sistemas de arquivos e seus pontos de montagem. Você só precisa saber quais tipos de sistemas de arquivos residem na memória procurando-os (por exemplo, wikipedia).

  1. Finally, if I open a memory-mapped file with vim, make some changes on it and save and close vim, what will happen? Will my changes simply be written to main memory? If that's the case, will other processes which use this file will see the changes I have just made? In my experience, the other processes did not see the changes I have made to the file when I made some changes on the file with vim. What is the reason for this?

Pessoalmente, eu não usei a função mmap em um programa em C, mas como eu entendê-lo de skimming man mmap e info mmap , não há mágica envolvidos na manutenção da representação na memória em sincronia. Na sua forma básica, chamando mmap copia o conteúdo do arquivo para a memória e msync é usado para escrevê-lo de volta da memória para o disco. Se o arquivo no disco mudar, não há nada lugar para detectar isso e modificar automaticamente a representação na memória em todos os processos que o mapearam.

EDIT: Acontece que mmap () realmente tenta manter a representação na memória em sincronia sob algumas condições. Se o mapa só for lido, ele será mantido em sincronia mesmo quando outros processos gravarem no arquivo. Se for escrito para (atribuindo à região de memória), o que acontece depende de quais dos flags MAP_SHARED ou MAP_PRIVATE aparentemente obrigatórios são fornecidos para mmap (). Se MAP_PRIVATE for fornecido, o mapa será forjado a partir da representação em disco e ficará em sincronia até você usar msync (). Se MAP_SHARED for fornecido, as atualizações serão visíveis para outros processos que tenham o arquivo mapeado, bem como (embora isso não seja imediatamente imediato) a representação em disco.

Acabei de abrir o vim em um arquivo existente e e executei o comando :w , enquanto tendo inotifywait -m . em execução em outro terminal. Entre alguns bits estranhos, esta é a parte importante que eu obtive de inotifywait .

./ MOVED_FROM e
./ MOVED_TO e~
./ CREATE e
./ OPEN e
./ MODIFY e
./ CLOSE_WRITE,CLOSE e
./ ATTRIB e
./ ATTRIB e
./ DELETE e~

O Vim cria um novo arquivo e remove o antigo. Por que isso acontece em vez de modificar o arquivo está além do escopo desta questão, mas o ponto é que este é um novo arquivo e, portanto, tem um novo inode.

Agora, o que você quer dizer com outros processos usando esse arquivo? Se você quer dizer processos que tinha o arquivo aberto enquanto você estava fazendo isso, não, eles não vão ver o alterar. Isso porque, apesar de abrirem um arquivo com o mesmo caminho, eles não são o mesmo arquivo. Se você quer dizer processos que podem abrir o arquivo depois de você fez isso, então sim, eles verão as mudanças. Eles estarão abrindo o novo arquivo você criou.

É importante observar que, embora os programas pareçam ter um arquivo aberto no interface do usuário, que não significa necessariamente que eles mantêm o arquivo aberto no processo. Vim é um exemplo disso, como mostrado acima.

    
por 13.09.2016 / 19:43

Tags