shell script: esegui un batch di N comandi in parallelo, attendi che tutto finisca, esegui il prossimo N


9

Attività: eseguire blocchi costituiti da 3-5 comandi (in parallelo / in background). Esempio di blocco:

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 &

Al termine, dovrebbe essere eseguito il blocco successivo. Suppongo che ciò possa essere fatto tramite i file di blocco:

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

Un certo numero di metodi per verificare se la directory è vuota può essere trovato qui , non so quale usare;

Domanda : un modo migliore per implementarlo?

PS Possibile metodo di segnalazione dello stato:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock

Ragazzi, non so cosa dire: tutte le risposte sono corrette, grazie!
Kagali-san,

Risposte:


8

Questo è esattamente lo scopo di gnu parallel , quindi ti consiglio vivamente di usarlo. In particolare, guardalo come un semaforo :

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

8

Forse qualche variazione su questo?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done

Ma sì, GNU parallelo è meglio se disponibile.
Eduardo Ivanec,


3

"wait" attende il completamento di tutti i processi in background. Campione:

dormire 30 e dormire 40 e dormire 120 e attendere

Attende il completamento di tutti i comandi, vale a dire almeno 120 secondi per questo esempio.

Spero che sia di aiuto.


0

Abbiamo provato a usare l' utilità sem GNU , come descritto da Phil Hollenback sopra, ma lo abbiamo trovato troppo pesante (oltre 300 istanze paralizzate la macchina). Ho cercato strumenti simili per implementare un semaforo di conteggio leggero ma non sono riuscito a trovare nulla di adatto.

Quindi ne ho implementato uno io stesso usando il gregge, si chiama semaforo .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.