Como garantir que o eco em um arquivo tenha sido liberado? [fechadas]

3

Eu tenho dois programas cooperativos, X e Y, rodando no mesmo sistema. X algumas vezes usa Y para calcular algumas informações. Eu uso comunicação baseada em arquivos entre os programas. Quando X quer que Y calcule algo, o processo é o seguinte:

  1. X escreve uma descrição de trabalho em um arquivo job.txt e a coloca em um diretório compartilhado. Então X começa a pesquisar a existência de um arquivo ready.txt nesse mesmo diretório.
  2. Y sondagens para existência do arquivo job.txt. Quando o arquivo é exibido, Y primeiro lê as informações do trabalho do arquivo e as exclui. Então Y executa o trabalho e coloca o resultado em result.txt. Finalmente Y cria um arquivo pronto.txt e novamente começa a pesquisar a existência de job.txt.
  3. Quando X percebe a aparência de ready.txt, ele lê o resultado.txt, exclui ambos ready.txt e result.txt e continua a fazer outra coisa.

O problema é que X às vezes recebe apenas um arquivo de resultado vazio ou parcial. Y usa um script bash que atualmente faz algo assim:

rm -f tmp_result.txt
for ((i=first; i <= last; i++)) # Each iteration produces 1 or more result lines
do
  # Compute something...
  echo "One result line with e.g. $values" >> tmp_result.txt
done
cp tmp_result.txt result.txt
touch ready.txt

Ou seja, o conteúdo do arquivo resultante é impresso uma linha por vez em um arquivo temporário usando o redirecionamento de eco e E / S. Quando o conteúdo estiver pronto (ou deverá estar pronto), ele será copiado para o arquivo result.txt final e X será notificado sobre isso criando o arquivo ready.txt.

Mesmo depois de muita experimentação e pesquisa, não consegui encontrar uma maneira de garantir que o X sempre receba resultados completos. Talvez 1 a 5 vezes em 100, X verá o resultado.txt como completamente vazio (o caso mais comum) ou contendo apenas resultados parciais.

Alguns esclarecimentos sobre a lógica do script: eu originalmente fiz eco das linhas de resultado diretamente para o result.txt, mas isso não era muito confiável (talvez 1 de 2 resultados estivessem incompletos). Então eu mudei para o primeiro eco as linhas em tmp_result.txt e, em seguida, mova (renomear) tmp_result.txt em result.txt. Isso resultou em talvez 1 de 10 resultados sendo incompletos. Copiar o arquivo, como mostrado acima, funcionou melhor, mas ainda ocasionalmente falha.

Então, como posso garantir que todas as linhas ecoadas foram copiadas corretamente para o resultado.txt antes que o X comece a ler o arquivo? Y tem apenas algumas instalações bash disponíveis.

EDIT: 2 3 comentários adicionais

  1. Eu verifiquei (por exemplo, não excluindo tmp_result.txt e depois inspecionando-o posteriormente) que o problema não está nos resultados originais, mas em como eles são transferidos para o X.
  2. Tanto o tmp_result.txt quanto o result.txt residem em discos RAM baseados no tmpfs, portanto, seria de esperar que copiar / mover arquivos fosse muito rápido.
  3. Eu primeiro encontrei o problema depois de começar a usar o tmpfs (originalmente todos os arquivos residiam em uma partição de disco rígido normal).
por user2781185 07.02.2016 / 23:02

2 respostas

2

Parece que você pode usar FIFOs para isso:

mkfifo tasks

Produtor:

for i in {1..10}; do echo "task$i"; done > tasks

Consumidor:

while read task; do echo "received $task"; done  <tasks

Com isso, você não precisa se preocupar com sincronização ou exclusão, e não perde tempo com a pesquisa - se não houver dados ou se o produtor ainda não tiver aberto o FIFO, o consumidor irá bloquear (e assim economizar tempo de CPU). Se o FIFO estiver cheio ou o consumidor não tiver aberto o FIFO, o produtor bloqueará.

    
por 08.02.2016 / 22:20
0

Tente colocar sync entre seu comando cp e touch ready.txt .

    
por 07.02.2016 / 23:13