Uma gravação menor do que 'PIPE_BUF' é considerada atômica. Isso deve ter pelo menos 512 bytes, embora possa facilmente ser maior (parece que o linux está configurado para 4096).
Isso pressupõe que você está falando de todos os componentes totalmente compatíveis com POSIX. Por exemplo, isso não é verdade no NFS.
Mas supondo que você grave em um arquivo de log aberto no modo 'O_APPEND' e mantenha suas linhas (incluindo nova linha) em bytes 'PIPE_BUF', você deve ser capaz de ter vários gravadores em um arquivo de log sem problemas de corrupção. Qualquer interrupção chegará antes ou depois da gravação, não no meio. Se você deseja que a integridade do arquivo sobreviva a uma reinicialização, você também precisará ligar fsync(2)
após cada gravação, mas isso é péssimo para o desempenho.
Esclarecimento : leia os comentários e a resposta de Oz Solomon . Não tenho certeza se isso O_APPEND
deveria ter esse PIPE_BUF
tamanho atomicidade. É inteiramente possível que seja apenas como o Linux foi implementado write()
, ou pode ser devido aos tamanhos de bloco do sistema de arquivos subjacente.
fsync(2)
oferece a mesma garantiasync(2)
e não tem tanto impacto sobre o desempenho.PIPE_BUF
nessa página se aplica apenas a canais e FIFOs, não a arquivos regulares.Editar: Atualizado em agosto de 2017 com os resultados mais recentes do Windows.
Vou lhe dar uma resposta com links para o código de teste e os resultados como autor da proposta Boost.AFIO, que implementa um sistema de arquivos assíncrono e uma biblioteca de arquivos i / o C ++.
Em primeiro lugar, O_APPEND ou o FILE_APPEND_DATA equivalente no Windows significa que os incrementos da extensão máxima do arquivo ("comprimento" do arquivo) são atômicos sob gravadores simultâneos. Isso é garantido pelo POSIX, e Linux, FreeBSD, OS X e Windows o implementam corretamente. O Samba também o implementa corretamente, o NFS anterior à v5 não, visto que falta a capacidade de formato de fio para anexar atomicamente. Portanto, se você abrir seu arquivo apenas com acréscimo, as gravações simultâneas não serão interrompidas entre si em nenhum sistema operacional principal, a menos que o NFS esteja envolvido.
No entanto, leituras simultâneas para anexos atômicos podem ter gravações interrompidas dependendo do sistema operacional, sistema de arquivamento e quais sinalizadores você abriu o arquivo - o incremento da extensão máxima do arquivo é atômico, mas a visibilidade das gravações em relação às leituras pode ou não seja atômico. Aqui está um rápido resumo por sinalizadores, sistema operacional e sistema de arquivamento:
Não O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 com NTFS: atualizar atomicidade = 1 byte até e incluindo 10.0.10240, de 10.0.14393 pelo menos 1Mb, provavelmente infinito (*).
Linux 4.2.6 com ext4: atualizar atomicidade = 1 byte
FreeBSD 10.2 com ZFS: atualizar atomicidade = pelo menos 1Mb, provavelmente infinito (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 com NTFS: atualize atomicidade = até e incluindo 10.0.10240 até 4096 bytes apenas se a página estiver alinhada, caso contrário, 512 bytes se FILE_FLAG_WRITE_THROUGH desativado, caso contrário, 64 bytes. Observe que essa atomicidade é provavelmente um recurso do PCIe DMA ao invés de projetado. Desde 10.0.14393, pelo menos 1Mb, provavelmente infinito (*).
Linux 4.2.6 com ext4: atomicidade de atualização = pelo menos 1Mb, provavelmente infinito (*). Observe que os Linuxes anteriores com ext4 definitivamente não excediam 4096 bytes, o XFS certamente costumava ter bloqueio personalizado, mas parece que o Linux recente finalmente corrigiu isso.
FreeBSD 10.2 com ZFS: atualizar atomicidade = pelo menos 1Mb, provavelmente infinito (*)
Você pode ver os resultados do teste empírico bruto em https://github.com/ned14/afio/tree/master/programs/fs-probe . Observe que testamos os deslocamentos interrompidos apenas em múltiplos de 512 bytes, então não posso dizer se uma atualização parcial de um setor de 512 bytes seria interrompida durante o ciclo de leitura-modificação-gravação.
Portanto, para responder à pergunta do OP, as gravações O_APPEND não interferirão umas com as outras, mas as leituras simultâneas às gravações O_APPEND provavelmente verão gravações interrompidas no Linux com ext4, a menos que O_DIRECT esteja ativado, após o que as gravações O_APPEND precisariam ser um múltiplo de tamanho de setor.
(*) "Provavelmente infinito" deriva dessas cláusulas na especificação POSIX:
e
mas inversamente:
Você pode ler mais sobre o significado disso nesta resposta
fonte
Eu escrevi um script para testar empiricamente o tamanho máximo do anexo atômico. O script, escrito em bash, gera vários processos de trabalho que gravam assinaturas específicas de trabalho no mesmo arquivo. Em seguida, ele lê o arquivo, procurando assinaturas sobrepostas ou corrompidas. Você pode ver a fonte do script nesta postagem do blog .
O tamanho real máximo de acréscimo atômico varia não apenas pelo sistema operacional, mas também 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.
fonte
echo $line >> $OUTPUT_FILE
isso resultará em uma única chamada para,write
independentemente do tamanho de$line
.Aqui está o que o padrão diz: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html .
fonte