Estou confuso com os arquivos mapeados na memória, então tenho algumas perguntas que ficaria muito feliz se você pudesse me ajudar.
- 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?
- Se isso for possível, é isso que chamamos de 'arquivo mapeado na memória'?
- Qual seria o significado de mover esse arquivo pelo sistema de arquivos (ou seja,
mv
inserir esse arquivo de um diretório para outro)? O que eu entendo é que, como o arquivo é mapeado na 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, usandovim
), lemos a região principal memória (portanto, nenhum disco está envolvido). Portanto, não importa para onde movemos o arquivo, ele sempre funcionará corretamente, certo? Se sim, mover o arquivo pelo sistema de arquivos tem algum significado? - Existe um comando que informa se um arquivo está mapeado na memória?
- Por fim, se eu abrir um arquivo mapeado na memória
vim
, faça algumas alterações e salve e fechevim
, o que acontecerá? Minhas alterações serão 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 arquivovim
. Qual é a razão para isto?
Respostas:
Os arquivos mapeados na memória funcionam ao contrário. O mapeamento de memória não é uma propriedade do arquivo, mas uma maneira de acessá-lo: 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 a gravação no arquivo; fazer isso envolve simplesmente ler e escrever na memória. O arquivo em si, no disco, é igual a qualquer outro arquivo.
Para configurar isso, os processos usam a
mmap
função Isso também pode ser usado para outros fins, como compartilhar memória entre processos.fonte
mv
.mv
simplesmente alteram as entradas de diretório, não os inodes (quando estão movendo arquivos no mesmo sistema de arquivos).lsof
. Ele não vai embora até que o processo chama munmap () ou saídas (ou substitui o mapeamento com um diferente usando mmap (MAP_FIXED) ...)Um arquivo mapeado na memória não é (necessariamente) suportado pela memória. Pode perfeitamente viver em um disco. Na verdade, o local onde um arquivo está não é uma propriedade do arquivo, 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 parece uma região regular da 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, gravá-lo e salvá-lo, a modificação será feita no arquivo, no disco (se estiver em um disco, é claro).
Isto pode ser usado por exemplo, quando você sabe que tem um monte de acessos para fazer em um arquivo, que não vão ser sequenciais, ser motivo pode ser mais fácil e mais eficiente para fazer leituras e gravações na memória do que a questão
read
,write
, ellseek
chamadas do sistema. O único problema com esse método é que você realmente não pode 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 em
/proc/<pid>/maps
(se o seu sistema o possuir).Para responder à sua segunda pergunta, quando você abre um arquivo, mesmo que você o mova no sistema de arquivos, os processos que o abriram ainda podem usá-lo. O que acontece é que um arquivo não depende de suas entradas nos sistemas de arquivos. Desde que você tenha um arquivo aberto, você tem um "identificador", um descritor de arquivo, que permite ler e gravar nele, mesmo que o 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.
fonte
/proc/<pid>/maps
. - Desde que o referido processo viva em um sistema que tenha um/proc
começo. O OpenBSD não, e o FreeBSD está eliminando gradualmente. Além disso, o FreeBSD possui em/proc/<pid>/map
vez de/proc/<pid>/maps
.O
lsof
comando mostrará todos os arquivos atualmente em uso pelo sistema. A coluna "FD" conterá "mem" se o arquivo estiver mapeado na memória. Portanto, você pode receber a saída desse comando pelo nome do arquivo em que está interessado.fonte
lsof -ad mem /path/to/file
lsof -ad mem,txt /path/to/file
como os arquivos que estão sendo executados também têm partes deles mapeadas no espaço de endereço do processo, mas aparecem comotxt
nalsof
saída.Você parece estar confundindo mapeamento de memória com arquivos em sistemas de arquivos que residem na memória, além de outros conceitos como como os processos mantêm o acesso aos arquivos, mesmo quando eles são movidos.
Vou perguntar pergunta por pergunta para ver se consigo esclarecer as coisas.
Ele aponta para a memória principal se estiver em um sistema de arquivos que resida na memória, como procfs que normalmente é montado em / proc, ou sysfs que está em / sys ou tmpfs que às vezes está em / tmp.
Não. Como stephen-kitt disse, "mapeamento de memória" refere-se a uma maneira de acessar um arquivo "mapeando" na memória principal e trabalhando com ele lá, em vez de ler e escrever pedaços de cada vez por meio de funções como read () e Escreva().
Se você movê-lo dentro do mesmo sistema de arquivos, você está apenas movendo uma referência, um inode de um diretório para outro. Se houver programas que já tiveram esse arquivo aberto, eles ainda estarão acessando o mesmo arquivo porque já têm o inode em mãos por meio de um descritor de arquivo. Foi o que aconteceu com o arquivo table_name.idb que você mencionou em um comentário.
O Wossname já respondeu isso para arquivos mapeados na memória.
lsof
informará 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
oumount
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 pesquisando-os (por exemplo, na wikipedia).Pessoalmente, eu não usei ammap
função em um programa em C, mas como eu a entendo por skimmingman mmap
einfo mmap
, não há mágica envolvida em manter a representação na memória em sincronia. Em sua forma básica, chamar mmap copia o conteúdo do arquivo para a memória emsync
é usado para gravá-lo da memória para o disco. Se o arquivo em disco for alterado, não há nada para detectá-lo 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 sincronizada sob algumas condições. Se o mapa for apenas lido, ele será mantido sincronizado, mesmo quando outros processos forem gravados no arquivo. Se for gravado (atribuindo à região da memória), o que acontecerá depende de qual sinalizador MAP_SHARED ou MAP_PRIVATE aparentemente obrigatório é fornecido ao mmap (). Se MAP_PRIVATE for fornecido, o mapa bifurca-se da representação em disco e deixa de estar sincronizado até você usar msync (). Se MAP_SHARED for fornecido, as atualizações serão visíveis para outros processos que têm o arquivo mapeado, bem como (embora isso não seja necessariamente imediato) a representação em disco.
Acabei de abrir o vim em um arquivo existente
e
e executei o comando:w
enquantoinotifywait -m .
rodava em outro terminal. Entre alguns trechos estranhos, essa é a parte importante de que recebiinotifywait
.O Vim cria um novo arquivo e remove o antigo. Por que isso ocorre em vez de modificar o arquivo está além do escopo desta pergunta, mas o ponto é que este é um novo arquivo e, portanto, possui um novo inode.
Agora, o que você quer dizer com outros processos usando esse arquivo? Se você quer dizer processos que tiveram o arquivo aberto enquanto você fazia isso, eles não verão as alterações. Isso ocorre porque, embora eles tenham aberto 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 fazer isso, sim, eles verão as alterações. Eles abrirão o novo arquivo que você criou.
É importante observar que, embora os programas pareçam ter um arquivo aberto na interface do usuário, isso não significa necessariamente que eles mantêm o arquivo aberto no processo. O Vim é um exemplo disso, como mostrado acima.
fonte
write
função é alterar os dados do arquivo. Isso pode ou não significar a alteração do conteúdo do disco, mas seja o que for que envolva, é de responsabilidade do sistema de arquivos fazer o correto. Nesse caso, isso envolveria a modificação da página de memória mapeada e a marcação de suja.