Trivial-Parallelisierung
Hinweis. Diese Seite zeigt beispielhaft, wie die Abarbeitung einer Liste von gleichartigen Aufgaben nach dem Master-Worker-Shema in der Shell implementiert werden kann. Für die praktische Bearbeitung von Problemem dieses Typs am RRZ wird das RRZ-Tools jobber empfohlen. Die vorliegende Seite ist vor der Bereitstellung von jobber entstanden.
Auf dieser Seite wird beschrieben, wie man unabhängige Aufgaben („Tasks“) in einem einzigen Shell-Skript bei gleichzeitiger (paralleler) Ausführung mehrere Aufgaben abarbeiten kann. Dazu werden einfache Shell-Skripte gezeigt, die sich für eigene Bedürfnisse anpassen und erweitern lassen.
Das Hauptskript ist run-tasks
:
line no. |
run-tasks |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/bin/bash
if (( $# != 4)) then echo "Usage: run-tasks Nprocesses program taskID1 taskID2" 1>&2 exit 1 fi
Nprocesses=$1 # maximale Anzahl der Prozesse, die gleichzeitig laufen sollen program=$2 # Programm (oder Skript), das gleichzeitig ausgeführt werden soll taskID1=$3 # erste zu verwendende Task-ID (positive ganze Zahl) taskID2=$4 # letze zu verwendende Task-ID (positive ganze Zahl)
for task in $(seq $taskID1 $taskID2) do if (( $task - $taskID1 >= $Nprocesses )) then wait -n fi "$program" $task & done
wait
exit |
---|
Das Skript startet Tasks, d.h. das Programm (oder
Skript) program
mit Tasks-IDs im Bereich
von taskID1
bis taskID2
. Dabei
werden Nprocesses
Tasks gleichzeitig bearbeitet (oder
weniger, falls weniger Task-IDs als Nprocesses
vorhanden
sind). Wenn ein Task abgearbeitet ist, wird der nächste gestartet.
Ein einfaches Beispiel-Skript für program
ist :
line no. |
task-example1.sh |
1 2 3 4 5 6 |
#!/bin/bash
echo "task-example1.sh: emulating work on task $1" sleep 10
exit |
---|
Damit lässt sich die Arbeitsweise von run-tasks
demonstrieren:
shell$./run-tasks 3 ./task-example1.sh 11 15
task-example1.sh: emulating work on task 12 task-example1.sh: emulating work on task 11 task-example1.sh: emulating work on task 13 task-example1.sh: emulating work on task 14 task-example1.sh: emulating work on task 15
Den Effekt der Parallelisierung sieht man nur während der Ausführung: während der ersten 10 Sekunden werden Tasks 11 bis 13 gleichzeitig bearbeitet und anschließend Tasks 14 und 15.
Das zweite
Beispiel-program
task-example2.sh
zeigt
Erweiterungen, die man in aller Regel brauchen dürfte (Umleitung der
Ausgaben in eine eigene Log-Datei pro Task sowie sichern des
jeweiligen Status). Dazu wird das eigentliche Skript in die
Funktion main
verlagert:
line no. |
task-example2.sh |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/bash
task=$1
function main { echo "task-example2.sh: emulating work on task $task" sleep 10 }
logfile=task$task.log
main > $logfile 2>&1 status=$? echo "status=$status" >> $logfile
exit $status |
---|
Zu beachten ist, dass laufende Tasks möglicherweise nicht
beendet werden, wenn man run-tasks
abbricht. Im
Batch-Betrieb am RRZ ist aber sichergestellt, dass alle Nutzerprozesse
am Ende eines Batch-Jobs durch das Batch-System abgebrochen werden,
sodass im Batch-Betrieb keine Prozesse hängenbleiben
(d.h. unkontrolliert weiterlaufen) können.