Tubos quebrados! Problema com o uso de pipes nomeados para vincular dois programas autônomos [fechados]

2

Eu tenho dois programas de linha de comando que normalmente são executados em série em um sistema linux.

Execução típica para ambos os programas é simplesmente isso:

  1. O programa A é executado. É inserir um arquivo de texto simples e gera um arquivo de texto simples.
  2. O programa B é executado após A, sua entrada é o arquivo de texto que o programa A produziu. Também gera um arquivo de texto simples.

Nota: para ambos os programas acima, suas entradas e saídas são simplesmente caminhos para os respectivos arquivos de entrada e saída. Exemplo: $ prog_a /path/to/inputfile/dataIn.txt /path/to/outputfile/dataOut.txt $ prog_b /path/to/inputfile/dataOut.txt /path/to/outputfile/results.txt

Estes são programas desenvolvidos por terceiros. Assim, não podemos modificá-los facilmente (pelo menos não de maneira oportuna). No entanto, queremos acelerar a execução, executando-os em paralelo usando pipes nomeados. Os arquivos de dados são extremamente grandes, por vezes, e processamento paralelo, assumimos que iria acelerar as coisas. Eu fui encarregado deste projeto e procedi da seguinte forma.

Escreveu um script bash onde:

  1. Crie um pipe nomeado que vincule os dois programas. Chame isso de dataOut.pipe
  2. O programa A lê o arquivo de texto como de costume, mas em vez de gravar em um arquivo de texto como antes, ele grava no pipe criado na etapa 1, dataOut.pipe
  3. O programa B lê o canal que foi gerado pelo programa A.

O script bash parece com algo assim:

\#!/bin/bash
mkfifo dataOut.pipe
prog_b dataOut.pipe  results.txt &
prog_a dataIn.txt  dataOut.pipe
rm dataOut.pipe

Agora isso funciona ... às vezes ... Muitas vezes eu recebo um spitout de exceção java para stderror. E não consigo descobrir qual é exatamente o problema, mas acho que é algo ao longo da linha:

Poderia o programa B, às vezes, rodar mais rápido que A e limpar o tubo mais rápido do que A pode colocar dados nele, o que faz com que a coisa toda caia?

Se for esse o caso, o que é um trabalho fácil? Ou poderia haver algo mais acontecendo?

    
por Wikkyd 28.07.2017 / 01:39

1 resposta

0

Um canal quebrado significa que o escritor (prog_a) está tentando gravar em um canal que foi fechado pelo seu leitor (prog_b). Você não nos dá informações suficientes para descobrir por que o prog_b pára tão rapidamente.

Dito isso, você assume que prog_b lê seu arquivo de entrada sequencialmente até que o EOF seja atendido e processe cada linha à medida que são lidas, como um comando comum de filtro Unix. Você tem certeza disso? Se prog_b quer procurar em seu arquivo de entrada, ou mmap, você está condenado (mesmo para prog_a). E se prog_b quiser ler todas as linhas de entrada e somente então processá-las, dificilmente você conseguirá qualquer coisa paralelizando prog_a e prog_b porque prog_b iniciará seu processamento somente quando o pipe estiver fechado, ou seja, quando o prog_a tiver terminado.

    
por 28.07.2017 / 03:05