Como esperar pela execução de processos paralelizados e juntar as saídas?

5

Muito novo para fazer coisas no Unix, procurando criar um script que faça o seguinte na ordem:

  • Pegue o arquivo .tsv principal, dividido em um número X de arquivos com linhas Y cada
  • Executar cada arquivo dividido por meio de um programa, que gera um novo arquivo .tsv após a conclusão
  • Aguarde até que TODOS os arquivos de divisão tenham concluído o processamento e, em seguida, agrupe os arquivos de saída em um.

Eu sei sobre o uso de split e sed para dividir arquivos, e não consigo imaginar que os arquivos de divisão executados em um script Python também sejam difíceis, mas o problema é descobrir quando todas as execuções da versão paralelizada programas estão completos e, em seguida, costurando suas saídas em um.

Com split , eu sei que ele incrementa automaticamente os nomes e que você pode paralelizá-lo em massa como visto nesta pergunta SO , então eu poderia descobrir essa parte para fora. Existe uma maneira de verificar o status de execução de um grupo de scripts Python paralelizados? Como eu poderia realizar o que gostaria de fazer?

    
por Befall 30.10.2014 / 01:16

2 respostas

3
split -l $Y main.tsv main_part_
for part in main_part_*; do
    program $part &
done
wait
echo "all done"

wait é um bash incorporado: verifique a página do manual para detalhes

    
por 30.10.2014 / 02:18
2

Como Gilles já indicou em um comentário. O paralelo GNU é ideal para este trabalho, pois possui recursos integrados para dividir e manter a ordem dos segmentos divididos para reingressar. Normalmente, ele é dividido em linhas, mas você pode especificar o início e término do registro específico para isso, bem como repetir um cabeçalho para todos os trabalhos divididos (se .tsv forem arquivos de valores separados por tabulações, pode ser o cabeçalho da coluna e mais fácil escrever seu programa de processamento). Eu usei isso para paralelizar a execução de xz .

Este trabalho é mais fácil se o seu programa de processamento for um filtro, recebendo entrada de stdin e escrevendo a saída para stdout. A seguir, suponha que seu programa python seja chamado de xyz

A invocação básica seria

cat input.tsv | parallel --pipe -k xyz > output.tsv

A opção --pipe faz interpretar paralelamente a entrada como dados para dividir e para ser enviada ao programa a ser chamado (ela tem outros modos) e a -k mantém a saída ordenada.

A seção de manual sobre --pipe entra em detalhes sobre o tamanho do bloco; registrar início e fim (que por padrão são copiados, mas podem ser suprimidos); e cabeçalho repetido.

Se o seu programa xyz precisar de opções de linha de comando, você pode especificá-los na linha de comando antes do redirecionamento de saída ( > .. )

Se você tem uma versão recente (você deve mesmo assim) você pode usar a opção mais eficiente --pipepart , assumindo que a entrada é um arquivo (ou seja, buscável) e o registro e a contagem de linhas não é usado:

 parallel -a input.tsv --pipepart -k xyz > output.tsv
    
por 30.10.2014 / 04:55

Tags