Ich habe eine Reihe von PNG-Bildern in einem Verzeichnis. Ich habe eine Anwendung namens pngout, die ich ausführe, um diese Bilder zu komprimieren. Diese Anwendung wird von einem Skript aufgerufen, das ich erstellt habe. Das Problem ist, dass dieses Skript eines nach dem anderen macht, etwa so:
FILES=(./*.png)
for f in "${FILES[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 $f R${f/.//}
done
Nur eine Datei auf einmal zu verarbeiten, nimmt viel Zeit in Anspruch. Nachdem ich diese App ausgeführt habe, sehe ich, dass die CPU nur 10 % beträgt. Also entdeckte ich, dass ich diese Dateien in 4 Stapel aufteilen, jeden Stapel in ein Verzeichnis legen und 4 von vier Terminalfenstern aus vier Prozesse auslösen kann, sodass ich vier Instanzen meines Skripts gleichzeitig habe, die diese Bilder und die verarbeiten Job dauert 1/4 der Zeit.
Das zweite Problem ist, dass ich Zeit verloren habe, die Bilder und Stapel aufzuteilen und das Skript in vier Verzeichnisse zu kopieren, 4 Terminalfenster zu öffnen, bla bla …
Wie macht man das mit einem Skript, ohne etwas teilen zu müssen?
Ich meine zwei Dinge:Erstens, wie feuere ich aus einem Bash-Skript einen Prozess in den Hintergrund? (Einfach &am Ende hinzufügen?) Zweitens:Wie stoppe ich das Senden von Aufgaben in den Hintergrund, nachdem ich die vierte Aufgabe gesendet habe, und lasse das Skript warten, bis die Aufgaben beendet sind? Ich meine, einfach eine neue Aufgabe in den Hintergrund schicken, wenn eine Aufgabe endet, und immer 4 Aufgaben parallel halten? Wenn ich das nicht tue, wird die Schleife Millionen von Tasks in den Hintergrund feuern und die CPU verstopfen.
Akzeptierte Antwort:
Wenn Sie eine Kopie von xargs
haben das die parallele Ausführung mit -P
unterstützt , können Sie einfach tun
printf '%s