2017-04-22 1 views
0

Was ich einfach tun möchte, ist warten auf Release-Sperre.Starten Sie Programme in Bash synchronisiert

Ich habe zum Beispiel 4 gleiche Skript (weil ich 4 Kern), die jeweils auf einem Teil eines Projekts jedes Skript funktioniert sieht wie folgt aus:

#!/bin/bash 
./prerenderscript $1 
scriptsync step1 4 
./renderscript $1 
scriptsync step2 4 
./postprod $1 

, wenn ich das Haupt-Skript ausführen, die die vier nennen Skript, ich möchte, dass jedes Skript einzeln funktioniert, aber irgendwann möchte ich, dass jedes Skript auf einander wartet, weil der nächste Teil alle Daten aus dem ersten Teil benötigt.

Für jetzt habe ich einige Logik wie die Anzahl der Dateien oder eine Datei, die für jeden Prozess erstellt und ihre Existenz mit anderen getestet werden.

Ich habe auch die Idee, eine Make-Datei zu verwenden und

prerender%: source 
    ./prerender [email protected] 
renderscript%: prerender1 prerender2 prerender3 prerender4 
    ./renderscript [email protected] 
postprod: renderscript1 renderscript2 renderscript3 renderscript4 
    ./postprod [email protected] 

Aber eigentlich der Prozess vereinfacht wird hier hat das Skript komplexer ist und für jeden den Faden muß Schritt seine Variablen halten.

Gibt es trotzdem, um das Skript synchron anstelle des Platzhalterbefehls scriptsync zu erhalten.

+0

Ich würde ein Python-Skript als Wrapper verwenden und mit 'threading' arbeiten. Auf diese Weise könnte ich meine Shell-Skripts wiederverwenden und vom Python-Threading und anderen Funktionen profitieren. –

+0

@ansi_lumen: 'threading' ist in' python' wegen der GIL nicht immer angemessen, es hängt von der Auslastung ab. – cdarke

+1

@cdarke. Wahr. Man kann immer noch 'multiprocessing' verwenden und echte Prozesse ausführen, wenn' threading' nicht gut skaliert. Die Hauptidee war, eine Umgebung zu verwenden, die das Threading/Forking einfacher als 'bash' behandelt. –

Antwort

0

Um dies in Bash zu erreichen, besteht eine Möglichkeit darin, die Interprozesskommunikation zu verwenden, damit eine Task auf den Abschluss der vorherigen Task wartet. Hier ist ein Beispiel.

#!/bin/bash 

# $1 is received to allow for an example command, not required for the mechanism suggested 
task_a() 
{ 
# Do some work 
sleep $1 # This is just a dummy command as an example 
echo "Task A/$1 completed" >&2 
# Send status to stdin, telling next task to proceed 
echo "OK" 
} 

task_b() 
{ 
IFS= read status ; [[ $status = OK ]] || return 1 
# Do some work 
sleep $1 # This is just a dummy command as an example 
echo "Task B/$1 completed" >&2 
} 

task_a 2 | task_b 2 & 
task_a 1 | task_b 1 & 
wait 

Sie werden feststellen, dass die read überall in Aufgabe B sein könnte, so könnten Sie einige Arbeit tun, dann warten (read) für die andere Aufgabe, dann weiter. Sie könnten viele Signale von Task A an Task B und mehrere entsprechende read-Anweisungen senden.

Wie im Beispiel gezeigt, können Sie mehrere Pipelines parallel starten.

Eine Grenze dieses Ansatzes besteht darin, dass eine Pipeline einen Kommunikationskanal zwischen einem Schreiber und einem Leser herstellt. Wenn eine Task auf Signale mehrerer Tasks warten muss, benötigen Sie FIFOs, damit die Task mit Abhängigkeiten von mehreren Quellen lesen kann.

Verwandte Themen