Frage Ein besserer Unix-Fund mit Parallelverarbeitung?


Das Unix find(1) Das Dienstprogramm ist sehr nützlich, um eine Aktion für viele Dateien auszuführen, die bestimmten Spezifikationen entsprechen, z.

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

Das obige Skript führt möglicherweise ein Skript oder ein Tool über jede XML-Datei in einem bestimmten Verzeichnis aus.

Nehmen wir an, mein Skript / Programm benötigt viel CPU-Zeit und ich habe 8 Prozessoren. Es wäre nett, bis zu 8 Dateien gleichzeitig zu verarbeiten.

GNU make ermöglicht parallele Jobverarbeitung mit dem -j Flagge aber find scheint keine solche Funktionalität zu haben. Gibt es eine alternative generische Job-Scheduling-Methode, um dies zu erreichen?


36
2017-10-21 09:07


Ursprung




Antworten:


xargs mit dem -P Option (Anzahl der Prozesse). Angenommen, ich möchte alle Logdateien in einem Verzeichnis auf einem 4-CPU-Rechner komprimieren:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

Du kannst auch sagen -n <number> für die maximale Anzahl von Arbeitseinheiten pro Prozess. Also sag ich hatte 2500 Dateien und ich sagte:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

Dies würde beginnen 4 bzip2 Prozesse, von denen jeder mit 500 Dateien und dann, wenn der erste fertig war, würde für die letzten 500 Dateien gestartet werden.

Nicht sicher, warum die vorherige Antwort verwendet xargs  und  makeDu hast dort zwei parallele Motoren!


51
2017-10-23 16:33



Bei find / xargs müssen Sie Folgendes beachten: Standardwerte für Zeilenumbrüche werden als Ausgabetrennzeichen gefunden. Bei xargs wird jedoch standardmäßig ein beliebiges Leerzeichen als Eingabetrennzeichen verwendet. Verwenden Sie -0 für beide, um sicher zu sein, oder wechseln Sie zu GNU parallel, das standardmäßig auf Zeilenumbrüche als Eingabetrennzeichen (übereinstimmende Suche) gesetzt ist. - ephemient
Wow, großartig! Ich habe nur überprüft, und es ist wahr, Xargs hat eine -P Möglichkeit! - PP.


GNU parallel kann auch helfen.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

Beachten Sie, dass ohne -j8 Streit, parallel Voreingestellt ist die Anzahl der Kerne auf Ihrer Maschine :-)


28
2017-10-23 22:07





Keine Notwendigkeit zu "reparieren" find - Gebrauch machen von make selbst, um die Parallelität zu handhaben.

Lassen Sie Ihren Prozess eine Protokolldatei oder eine andere Ausgabedatei erstellen und verwenden Sie dann ein Makefile wie folgt:

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

und rief so auf:

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

Besser noch, wenn Sie sicherstellen, dass die Ausgabedatei erst nach erfolgreichem Abschluss des Java-Prozesses erstellt wird, können Sie davon profitieren make's Abhängigkeitsverwaltung, um sicherzustellen, dass beim nächsten Mal nur unverarbeitete Dateien bearbeitet werden.


5
2017-10-21 09:24



Brillant! Vielen Dank. - PP.
Hoffentlich gibt es keine Leerzeichen oder andere "interessante" Zeichen in diesen Dateinamen; Make geht nicht sehr elegant damit um. - ephemient
Exzellente Idee! Ich habe nie daran gedacht, Makefiles wie diese zu verwenden. - oscfri


Find verfügt über eine parallele Option, die Sie direkt mit dem "+" - Symbol verwenden können. keine Xargs erforderlich. Wenn Sie es mit Grep kombinieren, kann es schnell durch Ihren Baum rasen und nach Streichhölzern suchen. Wenn ich beispielsweise nach allen Dateien in meinem Quellenverzeichnis suche, die die Zeichenfolge 'foo' enthalten, kann ich sie aufrufen
find sources -type f -exec grep -H foo {} +


2
2018-05-30 09:15



Wenn Sie das Suchhandbuch lesen, können Sie sehen, dass das -exec command + Syntax führt es nicht parallel, aber "gruppieren" viele Dateien zusammen und führen Sie den Befehl mit mehreren Dateien als Argumente gleichzeitig. Es kommt vor, dass grep parallel seine Ziele durchsehen kann. - Gyscos