Ich habe eine Aufgabe, die eine Liste von Dateien auf stdin verarbeitet. Die Startzeit des Programms ist beträchtlich und die Zeit, die jede Datei benötigt, ist sehr unterschiedlich. Ich möchte eine beträchtliche Anzahl dieser Prozesse erzeugen und dann die Arbeit an diejenigen senden, die nicht beschäftigt sind. Es gibt verschiedene Kommandozeilen-Tools, die beinahe das tun, was ich will. Ich habe sie auf zwei beinahe funktionierende Optionen eingegrenzt:
find . -type f | split -n r/24 -u --filter="myjob"
find . -type f | parallel --pipe -u -l 1 myjob
Das Problem ist, dass split
ein reines Round-Robin-Verfahren durchgeführt wird, sodass einer der Prozesse zurückbleibt und den Abschluss der gesamten Operation verzögert. while parallel
möchte einen Prozess pro N Zeilen oder Bytes an Eingaben erzeugen, und ich verbringe viel zu viel Zeit mit dem Start-Overhead.
Gibt es so etwas, das die Prozesse und Zuleitungen zu den Prozessen wiederverwendet, bei denen die Blockierung aufgehoben wurde?
myjob
bereit ist, mehr Input zu erhalten. Es gibt keine Möglichkeit zu wissen, dass ein Programm bereit ist, mehr Eingaben zu verarbeiten. Sie können nur wissen, dass ein Puffer (ein Pipe-Puffer, ein Stdio-Puffer) bereit ist, mehr Eingaben zu empfangen. Können Sie veranlassen, dass Ihr Programm eine Anfrage sendet (z. B. eine Eingabeaufforderung anzeigt), wenn es fertig ist?
read
Aufrufe reagiert, den Trick ausführen. Das ist ein ziemlich großer Programmieraufwand.
-l 1
in den parallel
Args? IIRC, das parallel anweist, eine Eingabezeile pro Job zu verarbeiten (dh einen Dateinamen pro Fork von myjob, also viel Start-Overhead).
split
Befehl? Der Name steht in Konflikt mit dem Standarddienstprogramm für die Textverarbeitung.