reescreve o arquivo existente para que ele seja substituído pela nova versão atomicamente, somente uma vez totalmente escrito

17

Eu me lembro vagamente de ler em algum lugar que costumava haver, em alguns Unices, uma maneira de abrir um arquivo existente para escrever, com um sinalizador que pedia ao kernel para usar a versão antiga (para outros processos acessando-o para leitura), até a "nova" versão foi totalmente escrita (fd fechado), a partir do qual o arquivo apareceu como a nova versão.

Em outras palavras, outros processos viram a versão antiga, ou a nova, nunca escrita de forma incompleta.

Alguém conhecido pode me indicar uma referência?

    
por eudoxos 11.11.2011 / 12:36

3 respostas

13

O que você está descrevendo soa exatamente como uma renomeação básica para substituir um arquivo.

Quando você renomeia / move um arquivo em cima do outro, o arquivo antigo é desvinculado. O que significa que o arquivo ainda existe, mas não está mais na árvore do sistema de arquivos. Assim, os aplicativos antigos continuarão a poder acessar o arquivo, desde que o mantenham aberto. Depois que todos os aplicativos fecharem o arquivo antigo, ele não será realmente alocado no disco.

A chamada do sistema rename é uma operação atômica. Portanto, para fazer isso, crie um novo arquivo com um nome diferente e, em seguida, chame rename para renomear o arquivo temporário como o que você deseja substituir. Como a operação é atômica, não há absolutamente nenhum período em que o arquivo esteja ausente. Vai instantaneamente do arquivo antigo para o novo arquivo.
Observe, entretanto, que o arquivo temporário e o arquivo que está sendo substituído devem residir no mesmo ponto de montagem.

    
por 29.03.2012 / 05:38
6

Como Patrick escreve , a maneira usual de fazer isso é escrever a nova versão em um arquivo separado, e quando terminar renomeie a nova versão para o nome do arquivo antigo, substituindo-o atomicamente. Esta segunda operação é chamada de substituir por renomear .

Agora, algumas referências:

por 19.08.2012 / 01:29
1

Isso me faz lembrar de Allocate On Flush . Quando um sistema de arquivos usa esse recurso, em vez de gravar dados diretamente no disco, ele subtrai o tamanho dos dados a serem gravados do contador de espaço livre do disco e armazena os dados na memória até que uma chamada de sistema de sincronização seja executada ou o kernel decida para limpar os buffers sujos.

Nesse caso, se o arquivo estiver sendo modificado por um processo e for aberto por outro processo, o último processo "verá" a versão não modificada ( ou "old", se preferir ) do arquivo.

Naturalmente, os itens acima são teóricos e dependem de vários fatores, e eu diria que é um pouco imprevisível - uma vez que você não sabe exatamente quando o kernel irá liberar as páginas sujas. Por exemplo, no Linux (como você também pode ler na seção 15.3 do Entendendo o Kernel do Linux), as páginas sujas são gravadas no disco sob as seguintes condições:

  • O cache da página fica muito cheio e mais páginas são necessárias, ou o número de páginas sujas fica muito grande.

  • Muito tempo se passou desde que uma página ficou suja.

  • Um processo solicita que todas as alterações pendentes de um dispositivo de bloco ou de um determinado arquivo sejam liberadas; ele faz isso invocando uma chamada de sistema sync (), fsync () ou fdatasync ().

Esse recurso é conhecido por ser implementado nos sistemas de arquivos HFS +, XFS, Reiser4, ZFS, Btrfs e ext4.

    
por 29.11.2011 / 12:21