Shell-Skript: Führen Sie einen Stapel von N Befehlen parallel aus, warten Sie, bis alle fertig sind, und führen Sie das nächste N aus

9

Aufgabe: Ausführen von Blöcken aus 3-5 Befehlen (parallel / im Hintergrund). Beispielblock:

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 &

Wenn es fertig ist, sollte der nächste Block ausgeführt werden. Ich nehme an, dies kann über Sperrdateien erfolgen:

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

Eine Reihe von Methoden zum Überprüfen, ob das Verzeichnis leer ist, finden Sie hier. Sie sind sich nicht sicher, welche Sie verwenden sollen.

Frage : Gibt es einen besseren Weg, dies umzusetzen?

PS Mögliche Methode zur Statusmeldung:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock
Kagali-San
quelle
Leute, wisst einfach nicht was ich sagen soll: Alle Antworten sind richtig, danke!
Kagali-San

Antworten:

8

Genau dafür wurde gnu parallel entwickelt. Ich empfehle daher dringend, es zu verwenden. Betrachten Sie insbesondere das Ausführen als Semaphor :

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
quelle
8

Vielleicht eine Variation davon?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done
Eduardo Ivanec
quelle
Aber ja, GNU parallel ist besser, wenn verfügbar.
Eduardo Ivanec
3

"wait" wartet, bis alle Hintergrundjobs abgeschlossen sind. Stichprobe:

30 schlafen & 40 schlafen & 120 schlafen & warten

Es wartet, bis alle Befehle abgeschlossen sind, dh mindestens 120 Sekunden für dieses Beispiel.

Hoffe das hilft.

Harri
quelle
0

Wir haben versucht, das GNU sem-Dienstprogramm zu verwenden , wie oben von Phil Hollenback beschrieben, fanden es jedoch zu schwer (mehr als 300 Instanzen haben die Maschine lahmgelegt). Ich habe mich nach ähnlichen Werkzeugen umgesehen, um ein leichtes Zählsemaphor zu implementieren, konnte aber nichts Passendes finden.

Also habe ich selbst eine mit Flock implementiert, sie heißt semaphorisch .

Tim Bunce
quelle