Gravação simultânea em um arquivo de log de muitos processos

3

Ao imitar o comando open do terminal do MacOS ou start do terminal da janela, os comentários de esta resposta sugerem a adição de stdout e stderr para ~/.xsession-errors , algo como ( bash ):

alias open='&>>~/.xsession-errors xdg-open'

A questão que vejo com isso são as condições da corrida. lsof ~/.xsession-errors mostra 22 processos com o arquivo aberto para gravação.

Como se evita que dois processos gravem no mesmo deslocamento em ~/.xsession-errors ?

    
por Tom Hale 19.02.2017 / 06:35

2 respostas

4

Quando um arquivo é aberto no modo de anexação, o sistema operacional garante que todas as gravações ocorram no final. Assim, os dados de um escritor não substituirão os dados de outro gravador.

Isso se aplica somente se o arquivo for aberto no modo de acréscimo, ou seja, com >> no shell. Se o criador do arquivo abrir com > , essa garantia não será aplicada e é possível ter essa sequência:

  • Processo 1: >out ; agora na posição 0
  • Processo 2: >>out ; agora na posição 0
  • Processo 1: escreva hello , agora na posição 6
  • Processo 2: escreva world , isto está escrito na posição 6 e o processo 2 está agora na posição 12
  • Processo 1: escreva oops , isto está escrito na posição 6 porque a posição do arquivo do processo 1 não mudou.

No Debian (desde 2001 ou por aí), o arquivo .xsession-errors é criado por '/ etc / X11 / Xsession e é aberto no modo append, então está tudo bem:

 exec >>"$ERRFILE" 2>&1

Não sei se esse é o caso em todas as distribuições que registram em ~/.xsession-errors .

Enquanto todos abrirem o arquivo no modo append, todas as saídas estarão presentes. A saída pode ser fragmentada no entanto. Na prática, pequenas gravações suficientes em um arquivo regular são atômicas. Qualquer coisa menor que 512B deve ser pequena o suficiente em todos os lugares, e acho que o Linux garante mais do que isso¹. Assim, cada linha de log deve aparecer intacta, mesmo com vários escritores concorrentes, supondo que os escritores usem saída com buffer de linha e que as linhas não sejam excessivamente longas.

¹ Observe que o POSIX não garante nada, exceto para pipes.

    
por 20.02.2017 / 00:42
1

Usar >> em um shell POSIX garante que o arquivo será aberto com O_APPEND .

A edição 7 das especificações do Open Group Base afirma:

If the O_APPEND flag of the file status flags is set, the file offset shall be set to the end of the file prior to each write and no intervening file modification operation shall occur between changing the file offset and the write operation.

POSIX define o número mínimo de bytes que podem ser solicitados para serem escritos em um único write(2) ligue ( SSIZE_MAX = 32,767 ) . O valor de retorno é o número de bytes realmente escritos (atômico garantido).

No entanto

Nem todos os sistemas de arquivos estão em conformidade. Acrescentando a um arquivo de vários processos diz:

The caveat is that not all filesystems are POSIX-compatible. Two famous examples are NFS and the Hadoop Distributed File System (HDFS). On these networked filesystems, appends are simulated and subject to race conditions.

Nem todo mundo joga legal

Embora você possa abrir usando O_APPEND , os outros processos gravados no arquivo talvez não. Você pode verificar qualquer arquivo:

lsof +fg <file>

De maneira preocupante, quando executo lsof +fg ~/.xsession-errors , vejo não AP (append) sinalizador, sugerindo que os 22 processos em minha listagem (Manjaro Linux com base no Arch) não estão abrindo o arquivo com segurança.

Somente quando eu executo cat >> ~/.xsession-errors em outro shell, a linha de saída final inclui o AP flag:

cat       3099 ravi    1w   REG   W,AP,LG   0,48      963 1926479 .xsession-errors

Se alguém souber onde esta questão deve ser levantada a montante, por favor comente.

praticamente

Se todos os processos abrirem o arquivo localmente com:

  • open(2) e bandeira O_APPEND
  • fopen(3) e "a" flag
  • POSIX sh >> ou bash &>>

Em seguida, nenhum dado deve ser substituído por condições de corrida.

Graças a @Gilles answer por me apontar na direção certa.

    
por 20.02.2017 / 07:23