Pergunta

Em geral, o que podemos tomar para concedido quando anexar um arquivo em UNIX a partir de vários processos? É possível perder dados (um processo de substituir alterações do outro)? É possível que os dados se mutilado? (Por exemplo, cada processo é anexar uma linha por acréscimo para um arquivo de log, é possível que duas linhas se deformar?) Se o acréscimo não é atômica no sentido acima, então qual é a melhor forma de garantir a exclusão mútua?

Foi útil?

Solução

A gravação que está sob o tamanho do 'PIPE_BUF' é suposto ser atômica. Isso deve ser pelo menos 512 bytes, embora ele poderia facilmente ser maior (linux parece ter definido para 4096).

Esta supor que você está falando todos os componentes totalmente compatíveis com POSIX. Por exemplo, isso não é verdade em NFS.

Mas supondo que você escrever para um arquivo de log que você abriu no modo 'O_APPEND' e manter suas linhas (incluindo nova linha) sob 'PIPE_BUF' bytes de comprimento, você deve ser capaz de ter vários escritores para um arquivo de log, sem quaisquer problemas de corrupção. Quaisquer interrupções vai chegar antes ou depois da gravação, não no meio. Se você quiser integridade de arquivos para sobreviver a uma reinicialização, você também precisará fsync(2) chamada após cada escrita, mas isso é terrível para o desempenho.

Clarificação : ler os comentários e do Oz Solomon resposta . Eu não tenho certeza de que O_APPEND é suposto ter que atomicity tamanho PIPE_BUF. É inteiramente possível que ele é apenas como Linux implementado write(), ou pode ser devido a tamanhos de blocos do sistema de arquivos subjacente.

Outras dicas

Editar:. Atualizado agosto 2017 com resultados mais recentes do Windows

Eu vou lhe dar uma resposta com links para código de teste e resultados como o autor da proposta Boost.AFIO que implementa um sistema de arquivos assíncrona e arquivo i / o C ++ biblioteca.

Em primeiro lugar, O_APPEND ou o FILE_APPEND_DATA equivalente no meio do Windows que incrementos do ponto máximo de arquivo (arquivo de "comprimento") são atômicas sob escritores concorrentes. Isso é garantido por POSIX, e Linux, FreeBSD, OS X e Windows todos implementá-lo corretamente. Samba também implementa-lo corretamente, NFS antes v5 não como ela não tem a capacidade formato de fio para acrescentar atomicamente. Então, se você abrir o seu arquivo com append-only, escritas concorrentes não vai rasgar com respeito um ao outro em qualquer um dos principais OS , a menos NFS está envolvido.

No entanto concorrente para Anexa atômicas pode ver gravações rasgadas dependendo OS, sistema de arquivamento, e que bandeiras você abriu o arquivo com - o incremento da extensão de arquivo máximo é atômica, mas a visibilidade dos escreve com relação a lê pode ou não ser atômica. Aqui está um resumo rápido por bandeiras, OS e sistema de arquivamento:


Sem O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 com NTFS:. Atualização atomicity = 1 byte até e incluindo 10.0.10240, de 10.0.14393, pelo menos 1Mb, provavelmente infinito (*)

Linux 4.2.6 com ext4: update atomicity = 1 byte

FreeBSD 10.2 com ZFS: update atomicity = pelo menos 1Mb, provavelmente infinito (*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 com NTFS: update atomicity = até e incluindo 10.0.10240 até 4096 bytes somente se a página alinhada, caso contrário 512 bytes se FILE_FLAG_WRITE_THROUGH fora, else 64 bytes. Note-se que esta atomicidade é provavelmente uma característica do PCIe DMA em vez de projetado em. Desde 10.0.14393, pelo menos 1Mb, provavelmente infinito (*).

Linux 4.2.6 com ext4: update atomicity = pelo menos 1Mb, provavelmente infinito (*). Note-se que Linuxes anteriores com ext4 definitivamente não exceder 4096 bytes, XFS certamente costumava ter bloqueio costume, mas parece que Linux recente foi finalmente corrigido isso.

FreeBSD 10.2 com ZFS: update atomicity = pelo menos 1Mb, provavelmente infinito (*)


Você pode ver os resultados dos testes empíricos matérias em https: // github .com / ned14 / afio / árvore / master / programas / fs-sonda. teste nota que para as compensações rasgados somente em 512 múltiplos bytes, então não posso dizer se uma atualização parcial de um setor de 512 bytes iria rasgar durante o ciclo de leitura-modificação-gravação.

Assim, para responder à pergunta do OP, O_APPEND gravações não irá interferir uns com os outros, mas lê concorrente a gravações O_APPEND provavelmente vai ver as gravações rasgadas no Linux com o ext4 menos O_DIRECT está ligado, depois do que suas gravações O_APPEND teria de ser um setor tamanho múltipla.


(*) "Provavelmente infinita" decorre destas cláusulas no POSIX spec:

Todas as seguintes funções devem ser atômica com relação a cada outra nos efeitos previstos no POSIX.1-2008 quando operam em arquivos regulares ou links simbólicos ... [muitas funções] ... read () ... write () ... Se dois threads cada chamada uma destas funções, cada chamada deverá quer ver todos os efeitos previstos da outra chamada ou nenhum deles. [Fonte]

e

Gravações pode ser serializado com respeito a outras leituras e gravações. Se um read () dos dados de arquivo pode ser comprovada (por qualquer meio) para ocorrer após um write () dos dados, ele deve refletir que write (), mesmo que as chamadas são feitos por processos diferentes. [Fonte]

mas, inversamente:

Este volume de POSIX.1-2008 não especificar o comportamento de concorrente grava em um arquivo de vários processos. As candidaturas devem usar algum formar de controle de concorrência. [Fonte]

Você pode ler mais sobre o significado destes nesta resposta

Eu escrevi um script para testar empiricamente o tamanho máximo de acréscimo atômica. O roteiro, escrito em bash, gera vários processos de trabalho que todas as assinaturas específicas do trabalho de escrita para o mesmo arquivo. Em seguida, ele lê o arquivo, procurando sobreposição ou assinaturas corrompidos. Você pode ver a fonte para o script neste blog .

O tamanho máximo real de acréscimo atômica varia não só por OS, mas pelo sistema de arquivos.

No Linux + EXT3 o tamanho é 4096, e no Windows + NTFS o tamanho é 1024. Veja os comentários abaixo para mais tamanhos.

Aqui está o que a norma diz: http://www.opengroup.org /onlinepubs/009695399/functions/pwrite.html .

Se o sinalizador O_APPEND dos sinalizadores de status do arquivo é definido, o arquivo tiver sido compensado será definido para o final do arquivo antes de cada gravação e nenhuma operação de modificação do arquivo intervenção deve ocorrer entre alterar o arquivo de offset e a operação de gravação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top