bash multithreading - eine variable, mehrere processe

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
chr.gogolin
Beiträge: 441
Registriert: 12.10.2005 23:09:28
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

bash multithreading - eine variable, mehrere processe

Beitrag von chr.gogolin » 03.04.2008 17:52:28

Hallo,

vor kurzem benötigte ich ein Skript um auf einer Reihe von Rechnern per ssh verschiedene Befehle auszuführen.
Ziel war ein Skript, dass zunächst auf jedem der 40 Rechner einen der Aufrufe aus der Liste ausführt und sobald der Rechner fertig ist die restlichen Aufrufe der Reihe nach "nachschiebt", bis alle abgearbeitet sind. Dabei muss und soll nicht darauf gewartet werden bis alle 40 Rechner mit ihrem Auftrag fertig sind sondern jeder soll gleich wieder beschäftigt werden.

Meine Skript funktioniert zwar inzwischen (fast), aber das Problem der "Absprache" zwischen den einzelnen Prozessen ist nicht schön gelöst.

Da mein letztes Posting aus dem ursprüngliche Thread [1] dann etwas off topic war uns sich auch keiner gemeldet hat, versuche ich es hier noch mal.


Mein Skript funktioniert im Prinzip so:

Es wird eine Liste mit auszuführenden Programmaufrufen erstellt und in einen Array (CommandArray)
abgelegt und eine Liste mit den ips von in im Netz erreichbaren Rechnern ermittelt ($ipList). Letzteres mache ich mit "nmap".

Die eigentliche Verwaltung der Jobs mache ich dann über eine Schleife mit der eine Subshell für jede ssh-Verbindung gestartet wird.

Die einzelnen Subshells müssen nun aber wissen welche Jobs schon bearbeitet wurden/werde. Dazu müsste man eine Variable haben auf die alle Subshells lesend und schreibend zugreigen können. Das habe ich aber nicht hinbekommen. Selbst mit "export" bekommt man den Wert der Variable nicht wieder aus der Subshell heraus bevor diese beendet ist. Also nehme ich eine Datei um die Nummer des nächsten zu bearbeitenden Jobs zu speichern.

Code: Alles auswählen

for ip in $ipList
do
(
    read < ./jobstoberun JOBSTOBERUN
    while [ 1 ] ; do
	read < ./jobstoberun JOBSTOBERUN 
	if [ "$JOBSTOBERUN" -le 0 ] 
	then 
	    echo "[$JOBSTOBERUN]@$ip: no jobs left"
	    break 
	fi
	echo $(($JOBSTOBERUN-1)) > ./jobstoberun

	echo "[$JOBSTOBERUN]@$ip: ssh -l cgogolin $ip ${CommandArray[$JOBSTOBERUN]}"

	ssh -l cgogolin $ip ${CommandArray[$JOBSTOBERUN]}

	if [ "$?" != "0" ]; then
	    echo "[$JOBSTOBERUN]@$ip: job failed or aborted"
	    echo "${CommandArray[$JOBSTOBERUN]}" >> ./failedjobs.log
	    break
	else
	    echo "[$JOBSTOBERUN]@$ip: finished"
	fi
    done
)&
sleep 1
done

wait
Das ist leider nicht nur unelegant, sondern kann auch zu Problemen führen. Wenn zwei Prozesse zugleich auf die Datei lesend und schreibend zugreifen wollen, kann es passieren dass ich mit "read" keine Zahl, sondern wildes Buchstaben-Gewürche in die variable "$JOBSTOBERUN" schreibt, was dann natürlich zum Absturz führt.

Kann man das besser lösen?


[1] http://www.debianforum.de/forum/viewtop ... 19#p613219
"Linux supports the notion of a command line or a shell for the same reason that only children read books with only pictures in them." - Bill Garrett

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: bash multithreading - eine variable, mehrere processe

Beitrag von cosmac » 03.04.2008 19:24:04

hi,

Informationen, die im Dateisystem statt in einer Variablen gespeichert
werden, überleben auch einen Stromausfall. Für den Vorteil würde ich
auf ein wenig Eleganz verzichten.

Du könntest ein Verzeichnis "CommandArray" anlegen und für jeden Job
eine Datei erstellen. Wenn ein Job abgearbeitet ist, kann die Subshell die
Datei löschen, ohne dass was durcheinander kommt. Du könntest auch,
während es schon läuft, noch Jobs hinzufügen oder vorzeitig löschen.

Damit die Jobs in der richtigen Reihenfolge abgearbeitet werden, müssen
die Dateinamen mit "00", "01", ... beginnen. Wenn ein Job nur aus einem
Befehl besteht, der keine '/' enthält, kann der auch Teil des Namens sein.
Beware of programmers who carry screwdrivers.

chr.gogolin
Beiträge: 441
Registriert: 12.10.2005 23:09:28
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: bash multithreading - eine variable, mehrere processe

Beitrag von chr.gogolin » 04.04.2008 14:52:58

Das mit dem nachträglich hinzufügen und entfernen klingt gut...

Aber bleibt das Problem mit dem Gleichzeitigen Zugriff nicht bestehen? Kann es nicht sein, dass ein Prozess sich eine Datei "aussucht" und sie dann vor dem Beginn der Bearbeitung löscht und in der Zwischenzeit bereits ein andere Prozess ebenfalls diese Datei ausgesucht hat?

Man müsste das denke ich so machen, dass der Elternprozess, welcher die Subshells startet auch nachher die Aufgaben verteilt. Nur wie könnte man das implementieren?
"Linux supports the notion of a command line or a shell for the same reason that only children read books with only pictures in them." - Bill Garrett

Antworten