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 |
12345678910111213141516171819202122232425 |
#!/bin/bashif (( $# != 4))then echo "Usage: run-tasks Nprocesses program taskID1 taskID2" 1>&2 exit 1fiNprocesses=$1 # maximale Anzahl der Prozesse, die gleichzeitig laufen sollenprogram=$2 # Programm (oder Skript), das gleichzeitig ausgeführt werden solltaskID1=$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 &donewaitexit |
|---|
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 |
123456 |
#!/bin/bashecho "task-example1.sh: emulating work on task $1"sleep 10exit |
|---|
Damit lässt sich die Arbeitsweise von run-tasks
demonstrieren:
shell$./run-tasks 3 ./task-example1.sh 11 15task-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 |
1234567891011121314151617 |
#!/bin/bashtask=$1function main{ echo "task-example2.sh: emulating work on task $task" sleep 10}logfile=task$task.logmain > $logfile 2>&1status=$?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.