Eine begrenzte Anzahl von Kind-Prozessen parallel in bash ausführen?
Habe ich eine große Menge von Dateien, für die einige schwere Verarbeitung getan werden muss.
Diese Verarbeitung in einem einzelnen Thread, nutzt ein paar hundert MiB RAM (auf der Maschine verwendet, um den Auftrag zu starten) und dauert ein paar Minuten zu laufen.
Mein Aktueller Anwendungsfall ist zum start eines hadoop-Jobs auf die input-Daten, aber ich hatte das gleiche problem in anderen Fällen vor.
Um die volle Nutzung der verfügbaren CPU-Leistung will ich in der Lage laufen mehrere diese Aufgaben paralell.
Jedoch eine sehr einfache Beispiel-shell-Skript wie das Müll system-performance durch übermäßiges laden und austauschen:
find . -type f | while read name ;
do
some_heavy_processing_command ${name} &
done
Also, was ich will, ist im wesentlichen ähnlich zu dem, was "gmake -j4" nicht.
Ich weiß die bash unterstützt die "warten" - Befehl, aber das nur wartet bis alle Kind-Prozesse beendet sind. In der Vergangenheit habe ich erstellt, ein Skript muss ein 'ps' Befehl und dann die grep-die Kind-Prozesse nach Namen (ja, ich weiß ... hässlich).
Was ist der einfachste/sauberste/beste Lösung, um zu tun, was ich will?
Edit: Danke an Frederik: ja, in der Tat ist dies ein Duplikat von Wie begrenzen Sie die Anzahl der threads/sub-Prozesse in einer Funktion in bash
Das "xargs --max-procs=4" funktioniert wie ein Charme.
(Also ich habe auf meine eigene Frage)
InformationsquelleAutor der Frage Niels Basjes | 2011-07-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gesagt haben, dass Fredrik lässt den exzellenten Punkt, dass xargs macht genau das, was Sie wollen...
InformationsquelleAutor der Antwort Dunes
Ich weiß, ich bin spät zur party mit dieser Antwort, aber ich dachte, ich würde post eine alternative, die, IMHO, macht der Körper das Skript sauberer und einfacher. (Klar kann man die Werte ändern 2 & 5 werden für Ihr Szenario geeignet.)
InformationsquelleAutor der Antwort BruceH
Mit GNU Parallel wird es einfacher:
Erfahren Sie mehr: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
InformationsquelleAutor der Antwort Ole Tange
Ich glaube, ich fand die praktische Lösung mit :
Nennen, wie z.B. 'test.mak', und fügen Sie die execute-Rechte. Wenn Sie anrufen
./test.mak
es rufen diesome_heavy_processing_command
one-by-one. Aber Sie können rufen wie./test.mak -j 4
dann wird es laufen vier Teilprozesse auf einmal. Auch Sie können es auf eine elegantere Art: Ausführung als./test.mak -j 5 -l 1.5
dann wird es laufen maximal 5 sub-Prozesse und die Systemlast unter 1.5, aber es wird die Anzahl der Prozesse, wenn die Systemauslastung größer als 1,5.Es ist flexibler als xargs und ist Teil der standard-distribution, nicht wie
parallel
.InformationsquelleAutor der Antwort TrueY
Dieser code funktionierte ziemlich gut für mich.
Bemerkte ich ein Problem, bei dem das Skript konnte nicht zu Ende.
Wenn Sie in einem Fall, in dem das Skript nicht beenden aufgrund max_jobs größer als die Anzahl der Elemente im array, wird das script nie beendet.
Um zu verhindern, dass die oben genannten Szenario, ich habe die folgenden direkt nach der "max_jobs" Erklärung.
InformationsquelleAutor der Antwort masseo
Andere Möglichkeit:
InformationsquelleAutor der Antwort Jeff Kaufman
Hier ist eine sehr gute Funktion, die ich verwendet, um zu Steuern, die maximale Anzahl der jobs von der bash oder ksh. ANMERKUNG: die - 1 in der pgrep subtrahiert die wc -l Teilprozess.
InformationsquelleAutor der Antwort user2709129