shell script: executa um lote de N comandos em paralelo, espera que todos terminem, execute next N

7

Tarefa: executar blocos consistindo de 3 a 5 comandos (em paralelo / plano de fundo). Exemplo de bloco:

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 pode ser feito por meio 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 , don Não tenho certeza qual usar;

Pergunta : alguma maneira melhor de implementar isso?

P.S. Método de relatório de status possível:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock
    
por kagali-san 14.04.2011 / 05:29

5 respostas

6

Isso é exatamente o que o paralela do gnu foi projetado, então eu recomendo strongmente que você o use. Em particular, veja como é executado 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
    
por 14.04.2011 / 06:22
7

Talvez alguma variação disso?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done
    
por 14.04.2011 / 05:45
5

Você tem alguma razão em particular para não usar algo como GNU paralelo ? Se você precisar usar o bash, considere métodos como os descritos em este postagem do blog (aguarde e os pipes nomeados são úteis aqui).

    
por 14.04.2011 / 05:48
3

"espera" aguarda que todos os trabalhos em segundo plano sejam concluídos. Amostra:

dormir 30 & dormir 40 & sleep 120 & espera

Ele aguarda até que todos os comandos estejam completos, ou seja, pelo menos 120 segundos para este exemplo.

Espero que isso ajude.

    
por 14.04.2011 / 06:37
0

Nós tentamos usar o utilitário GNU sem , como descrito por Phil Hollenback acima, mas o encontramos peso muito pesado (300+ instâncias aleijaram a máquina). Procurei ferramentas semelhantes para implementar um semáforo de contagem leve, mas não consegui encontrar nada adequado.

Então, eu mesmo implementei um usando o flock, chamado semaphoric .

    
por 18.03.2015 / 14:10

Tags