Multi-Threading / bifurcação em um script bash

9

Eu escrevi um script bash que segue o seguinte formato:

#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"

rm -f $inFile $outFile

while read line
do

    -- Block of Commands

done < "$inFile"

end=$(date +%s)

runtime=$((end-start))

echo "Program has finished execution in $runtime seconds."

O loop while lerá de $inFile , realizará alguma atividade na linha e despejará o resultado em $outFile .

Como o $inFile tem mais de 3500 linhas, o script levaria de 6 a 7 horas para ser executado completamente. Para minimizar esse tempo, planejo usar multi-threading ou bifurcação neste script. Se eu criar 8 processos filhos, 8 linhas do $inFile serão processadas simultaneamente.

Como isso pode ser feito?

    
por Mandar Shinde 01.08.2014 / 07:44

1 resposta

10

O GNU parallel é feito exatamente para esse tipo de coisa. Você pode executar seu script várias vezes de uma vez, com dados diferentes da sua entrada inseridos para cada um:

cat input.txt | parallel --pipe your-script.sh

Por padrão, ele irá gerar processos de acordo com o número de processadores em seu sistema, mas você pode personalizar isso com -j N .

Um truque particularmente interessante é o recurso de embrulhar shebang. Se você alterar a primeira linha do seu script Bash para:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash

e alimenta os dados na entrada padrão, tudo acontecerá automaticamente. Isso é menos útil quando você tem um código de limpeza que precisa ser executado no final, o que você pode fazer.

Há algumas coisas a serem observadas. Uma é que ela vai dividir sua entrada em partes sequenciais e usar essas uma de cada vez - ela não intercala linhas. A outra é que esses fragmentos são divididos por tamanho, sem considerar quantos registros existem. Você pode usar --block N para definir um tamanho de bloco diferente em bytes. No seu caso, não mais do que um oitavo do tamanho do arquivo deve estar correto. Parece que seu arquivo pode ser pequeno o suficiente para acabar em um único bloco, o que poderia frustrar o propósito.

Há muitas opções para casos de uso diferentes, mas o tutorial aborda as coisas muito bem . Opções nas quais você também pode estar interessado incluem --round-robin e --group .

    
por 01.08.2014 / 09:07