Ich habe ein kleines Skript, das alle Dateien eines Ordners durchläuft und einen (normalerweise lang anhaltenden) Befehl ausführt. Im Grunde ist es
for file in ./folder/*;
do
./bin/myProgram $file > ./done/$file
done
(Bitte ignorieren Sie Syntaxfehler, es ist nur Pseudocode).
Ich wollte dieses Skript jetzt zweimal gleichzeitig ausführen. Offensichtlich ist die Ausführung nicht erforderlich, wenn ./done/$file vorhanden ist. Also habe ich das Skript in geändert
for file in ./folder/*;
do
[ -f ./done/$file ] || ./bin/myProgram $file >./done/$file
done
Grundsätzlich stellt sich also die Frage: Ist es möglich, dass sich beide Skripte (oder im Allgemeinen mehr als ein Skript) tatsächlich am selben Punkt befinden und prüfen, ob die fehlgeschlagene done
Datei vorhanden ist und der Befehl zweimal ausgeführt wird?
es wäre einfach perfekt, aber ich bezweifle es sehr. Dies wäre zu einfach: D Wenn es vorkommen kann, dass sie dieselbe Datei verarbeiten, ist es dann möglich, die Skripte irgendwie zu "synchronisieren"?
quelle
xargs
mit der-P
verfügbaren Option haben, lesen Sie diese Frage .done/$file
Markierungen scheinenmake
mir ein wenig wie Ziele zu sein.xargs
oder GNUmake
oder eine Version von habenparallel
, müssen Sie dieses spezielle Rad nicht neu erfinden.Antworten:
Dies ist möglich und tritt in der Realität auf. Verwenden Sie eine Sperrdatei , um diese Situation zu vermeiden. Ein Beispiel von dieser Seite:
quelle
Die beiden Instanzen Ihres Skripts können auf diese Weise interagieren, wodurch der Befehl zweimal ausgeführt wird. Dies wird als Rennbedingung bezeichnet .
Eine Möglichkeit, diese Race-Bedingung zu vermeiden, besteht darin, dass jede Instanz ihre Eingabedatei abruft, indem sie in ein anderes Verzeichnis verschoben wird. Das Verschieben einer Datei (innerhalb desselben Dateisystems) ist atomar . Das Verschieben der Eingabedateien ist möglicherweise nicht wünschenswert, und dies wird bereits etwas kompliziert.
Eine einfache Möglichkeit, die Dateien mit einem weit verbreiteten Tool parallel zu verarbeiten, ist GNU make , wobei das
-j
Flag für die parallele Ausführung verwendet wird . Hier ist ein Makefile für diese Aufgabe (denken Sie daran, Tabulatoren zum Einrücken von Befehlen zu verwenden):Ausführen
make -j 3
, um 3 Instanzen parallel auszuführen.Siehe auch Vier Aufgaben parallel ... wie mache ich das?
quelle
Ich habe das Gefühl, dass Sie wirklich versuchen, mehrere Jobs parallel auszuführen, und dass die Sperrdatei einfach ein Mittel zum Zweck ist.
Wenn Sie GNU Parallel http://www.gnu.org/software/parallel/ installiert haben, können Sie dies tun:
MyProgram wird auf jedem Kern parallel ausgeführt.
Sie können GNU Parallel einfach installieren, indem Sie:
Sehen Sie sich die Intro-Videos für GNU Parallel an, um mehr zu erfahren: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
quelle
Das Problem beim Sperren besteht darin, dass Sie eine Methode benötigen, die eine unterbrechungsfreie Sperre erstellt (manchmal auch als atomar bezeichnet). Wie Chris in seiner Antwort geschrieben hat,
mkdir
handelt es sich um eine solche unterbrechungsfreie Operation (das Erstellen einer Datei ist keine solche Operation).Es gibt auch einen Befehl auf hoher Ebene - normalerweise im
procmail
Paket versteckt :lockfile
. Dieser Befehl hat einige nette Funktionen und kann problemlos in Ihren eigenen Skripten verwendet werden, ohne dass Sie das Rad neu erfinden müssen (z. B. um Ihre eigene Funktion zu schreiben, die basierend auf der Verzeichniserstellung gesperrt wird).quelle