shell script: execute um lote de N comandos em paralelo, aguarde a conclusão de todos, execute o próximo N

9

Tarefa: execute blocos que consistam em 3-5 comandos (em paralelo / em segundo plano). Bloco de exemplo:

dd if=/dev/urandom of=/mnt/1/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/2/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/3/x bs=1024 count=1024000000 &

Quando terminar, o próximo bloco deverá ser executado. Suponho que isso possa ser feito através de arquivos de bloqueio:

task1.sh:

real_task1 real_param1 ; rm /var/lock/myscript/task1.lock

task2.sh:

real_task2 real_param1 ; rm /var/lock/myscript/task2.lock

...

taskgen.sh:

# loop
 # while directory isn't empty - wait...
 gen_tasks.pl # build task files from some queue
 for i in 1 2 3; do touch /var/lock/myscript/task$i.lock ; done
 ./task1.sh &
 ./task2.sh &
 ./task3.sh &
 # if task1.sh doesn't exits then exit, else loop waits for files to be deleted

Vários métodos para verificar se o diretório está vazio podem ser encontrados aqui , não sei qual usar;

Pergunta : existe alguma maneira melhor de implementar isso?

PS Possível método de relatório de status:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock
kagali-san
fonte
Gente, só não sei o que dizer: todas as respostas estão corretas, obrigado!
precisa saber é o seguinte

Respostas:

8

É exatamente para isso que o gnu paralelo foi projetado, então eu recomendo fortemente que você o use. Em particular, veja como executá-lo como um semáforo :

for i in {1..4}
do
  echo running $i
  sem -j3 df dd if=/dev/urandom of=/mnt/$i/x bs=1024 count=1024000000 ";" echo done
done
# sem --wait waits until all jobs are done.
sem --wait
Phil Hollenback
fonte
8

Talvez alguma variação nisso?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done
Eduardo Ivanec
fonte
Mas sim, o GNU paralelo é melhor se disponível.
Eduardo Ivanec
5

Você tem algum motivo específico para não usar algo como o GNU paralelo ? Se você deve usar o bash, considere métodos como os descritos nesta postagem do blog (espera e pipes nomeados são úteis aqui).

justarobert
fonte
3

"wait" aguarda a conclusão de todos os trabalhos em segundo plano. Amostra:

dormir 30 e dormir 40 e dormir 120 e esperar

Espera até que todos os comandos sejam concluídos, ou seja, pelo menos 120 segundos para este exemplo.

Espero que isto ajude.

Harri
fonte
0

Tentamos usar o utilitário GNU sem , como descrito por Phil Hollenback acima, mas achamos muito pesado (mais de 300 instâncias danificaram a máquina). Procurei ferramentas semelhantes para implementar um semáforo de contagem leve, mas não consegui encontrar nada adequado.

Então eu implementei um usando rebanho, é chamado de semáforo .

Tim Bunce
fonte