Ich versuche eine .sh-Datei zu schreiben , in der viele Programme gleichzeitig ausgeführt werden
Ich habe es versucht
prog1
prog2
Aber das läuft prog1, wartet dann bis prog1 endet und startet dann prog2 ...
Wie kann ich sie parallel ausführen?
bash
parallel-processing
Betamoo
quelle
quelle
wait
! Ja, in bash können Sie auf die untergeordneten Prozesse des Skripts warten.nohup
zu verhindern, dass das Programm beendet wird, wenn die Shell auflegt.Wie wäre es mit:
Dieser Wille:
prog1
.prog2
und halten Sie es im Vordergrund , damit Sie es mit schließen könnenctrl-c
.prog2
, werden Sie zurückkommenprog1
‚s Vordergrund , so können Sie auch in der Nähe mit ihmctrl-c
.quelle
prog1
wennprog2
beendet wird? Denken Sie annode srv.js & cucumberjs
prog1 & prog2 ; fg
Dies diente zum gleichzeitigen Ausführen mehrerer SSH-Tunnel. Hoffe das hilft jemandem.prog2
Sie wiederprog1
im Vordergrund stehen , wenn sie nicht sofort ausgeführt wird . Wenn dies wünschenswert ist, ist es in Ordnung.prog1 & prog2 && kill $!
.Sie können verwenden
wait
:Es weist die Hintergrundprogramm-PIDs Variablen zu (
$!
ist die PID des zuletzt gestarteten Prozesses), und derwait
Befehl wartet auf sie. Es ist schön, denn wenn Sie das Skript beenden, werden auch die Prozesse beendet!quelle
#!/usr/bin/env bash ARRAY='cat bat rat' for ARR in $ARRAY do ./run_script1 $ARR & done P1=$! wait $P1 echo "INFO: Execution of all background processes in the for loop has completed.."
${}
um es in eine Zeichenfolgenliste oder ähnliches zu interpolieren.Mit GNU Parallel http://www.gnu.org/software/parallel/ ist es so einfach wie:
Oder wenn Sie es vorziehen:
Mehr erfahren:
quelle
parallel
mit unterschiedlicher Syntax gibt. Bei Debian-Derivatenmoreutils
enthält das Paket beispielsweise einen anderen Befehl,parallel
der sich ganz anders verhält.parallel
besser als mit&
?parallel
ist besser, wenn mehr Jobs als Kerne vorhanden sind. In diesem Fall&
würden mehr als ein Job pro Kern gleichzeitig ausgeführt. (vgl. Pigeonhole-Prinzip )Wenn Sie in der Lage sein möchten, mehrere Prozesse einfach auszuführen und zu beenden,
ctrl-c
ist dies meine Lieblingsmethode:(…)
Mehrere Hintergrundprozesse in einer Subshell erzeugen und TrapSIGINT
ausführenkill 0
, wodurch alles getötet wird, was in der Subshell-Gruppe erzeugt wurde:Sie können komplexe Prozessausführung Strukturen haben, und alles wird in der Nähe mit einem einzigen
ctrl-c
(nur sicherstellen , dass der letzte Prozess im Vordergrund ausgeführt wird, das heißt, sie sind nicht&
nachprog1.3
):quelle
xargs -P <n>
ermöglicht es Ihnen,<n>
Befehle parallel auszuführen.Während
-P
eine nicht standardmäßige Option ist, unterstützen sie sowohl die GNU- (Linux) als auch die macOS / BSD-Implementierung.Das folgende Beispiel:
Die Ausgabe sieht ungefähr so aus:
Das Timing zeigt, dass die Befehle parallel ausgeführt wurden (der letzte Befehl wurde erst gestartet, nachdem der erste der ursprünglichen 3 beendet wurde, aber sehr schnell ausgeführt wurde).
Der
xargs
Befehl selbst wird erst zurückgegeben, wenn alle Befehle abgeschlossen sind. Sie können ihn jedoch im Hintergrund ausführen, indem Sie ihn mit dem Steuerungsoperator beenden&
und dann mit dem integriertenwait
Befehl warten, bis der gesamtexargs
Befehl abgeschlossen ist.Hinweis:
Bei BSD / macOS
xargs
müssen Sie die Anzahl der Befehle angeben, die explizit parallel ausgeführt werden sollen , während Sie bei GNUxargs
angeben können-P 0
, dass so viele Befehle wie möglich parallel ausgeführt werden sollen.Die Ausgabe der parallel ausgeführten Prozesse kommt an, während sie generiert wird , sodass sie unvorhersehbar verschachtelt wird .
parallel
Wie in der Antwort von Ole erwähnt ( bei den meisten Plattformen nicht Standard), serialisiert (gruppiert) GNU die Ausgabe bequem pro Prozess und bietet viele erweiterte Funktionen.quelle
Leiten Sie Fehler in separate Protokolle um.
quelle
prog1 2> .errorprog1.log & prog2 2> .errorprog2.log &
ls notthere1 & 2> .errorprog1.log; ls notthere2 & 2>.errorprog2.log
. Die Fehler gehen an die Konsole und beide Fehlerdateien sind leer. Wie @Dennis Williamson sagt,&
ist ein Trennzeichen wie;
: (a) es muss am Ende des Befehls stehen (nach jeder Umleitung), und (b) Sie brauchen das;
überhaupt nicht :-)Es gibt ein sehr nützliches Programm, das nohup aufruft.
quelle
nohup
An sich wird nichts im Hintergrund ausgeführt, und die Verwendungnohup
ist keine Voraussetzung oder Voraussetzung für die Ausführung von Aufgaben im Hintergrund. Sie sind oft zusammen nützlich, aber als solche beantwortet dies die Frage nicht.Hier ist eine Funktion, die ich verwende, um parallel mit maximal n Prozessen zu arbeiten (im Beispiel n = 4):
Wenn max_children auf die Anzahl der Kerne eingestellt ist, versucht diese Funktion, Leerlaufkerne zu vermeiden.
quelle
wait -n
erfordertbash
4.3+ und ändert die Logik so, dass darauf gewartet wird, dass einer der angegebenen / implizierten Prozesse beendet wird.Sie können ppss versuchen . ppss ist ziemlich leistungsfähig - Sie können sogar einen Mini-Cluster erstellen. xargs -P kann auch nützlich sein, wenn Sie eine Menge peinlich paralleler Verarbeitung zu erledigen haben.
quelle
Ich hatte kürzlich eine ähnliche Situation, in der ich mehrere Programme gleichzeitig ausführen, ihre Ausgaben in getrennte Protokolldateien umleiten und warten musste, bis sie fertig waren, und am Ende hatte ich Folgendes:
Quelle: http://joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
quelle
Prozess-Laich-Manager
Sicher, technisch gesehen sind dies Prozesse, und dieses Programm sollte eigentlich als Prozess-Spawning-Manager bezeichnet werden, aber dies liegt nur an der Funktionsweise von BASH, wenn es das kaufmännische Und verwendet, den Systemaufruf fork () oder vielleicht clone () verwendet Dies klont in einen separaten Speicherbereich und nicht in pthread_create (), das den Speicher gemeinsam nutzen würde. Wenn BASH Letzteres unterstützen würde, würde jede "Ausführungssequenz" genauso funktionieren und könnte als herkömmliche Threads bezeichnet werden, während ein effizienterer Speicherbedarf erzielt wird. Funktionell funktioniert es jedoch genauso, wenn auch etwas schwieriger, da nicht in jedem Worker-Klon GLOBAL-Variablen verfügbar sind, weshalb die prozessübergreifende Kommunikationsdatei und das rudimentäre Flock-Semaphor zur Verwaltung kritischer Abschnitte verwendet werden. Das Gabeln von BASH ist hier natürlich die grundlegende Antwort, aber ich habe das Gefühl, dass die Leute das wissen, aber wirklich versuchen, das zu verwalten, was erzeugt wird, anstatt es nur zu gabeln und zu vergessen. Dies zeigt eine Möglichkeit, bis zu 200 Instanzen von gegabelten Prozessen zu verwalten, die alle auf eine einzelne Ressource zugreifen. Natürlich ist das übertrieben, aber ich habe es genossen, es zu schreiben, also habe ich weitergemacht. Erhöhen Sie die Größe Ihres Terminals entsprechend. Ich hoffe, Sie finden das nützlich.
quelle
Ihr Skript sollte folgendermaßen aussehen:
Angenommen, Ihr System kann n Jobs gleichzeitig annehmen. Verwenden Sie wait, um jeweils nur n Jobs auszuführen.
quelle
Mit bashj ( https://sourceforge.net/projects/bashj/ ) sollten Sie nicht nur mehrere Prozesse ausführen können (wie von anderen vorgeschlagen), sondern auch mehrere Threads in einer JVM, die von Ihrem Skript aus gesteuert wird. Dies erfordert natürlich ein Java-JDK. Threads verbrauchen weniger Ressourcen als Prozesse.
Hier ist ein Arbeitscode:
quelle