gnu parallel: Leite die gesamte Standardeingabe an alle Prozesse weiter

gnu parallel: Leite die gesamte Standardeingabe an alle Prozesse weiter

Ich versuche, die Eingaben parallel auf verschiedene Arten zu verarbeiten und die resultierenden Zeilen so auszugeben, wie sie eingehen. Mein aktueller Ansatz ist folgender:

# process_parallel.sh
read input
parallel --colsep ' ' --linebuffer 'echo $input | {}' \
 ::: 'python process1.py' ./process2.sh ./process3

Der Kontext lässt sich etwa wie folgt zusammenfassen:

(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh

Das obige funktioniert, hat aber einen wichtigen Nachteil: Die Prozesse werden erst gestartet, wenn die Eingabe gelesen wurde. Ich möchte sie sofort starten, da das eine Weile dauern kann, und dann die gesamte Standardeingabe parallel an jeden von ihnen weiterleiten.

Wie erreiche ich das?

Antwort1

In GNU Parallel wurde ziemlich viel Arbeit investiert, damit kein neuer Job gestartet wird, wenn keine Daten vorhanden sind. Dies liegt daran, dass einige Programme schwer fehlschlagen, wenn sie keine Eingaben erhalten. Sie arbeiten also gegen das Design von GNU Parallel.

Um die Eingabe zu duplizieren, können Sie teedie Prozesssubstitution verwenden:

cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null

Es wird sofort gestartet process1: , process2, und process3. Die Ausgabe kann jedoch gemischt sein. Wenn die Ausgabe verwendet werden muss, sollten Sie sie also in verschiedene Dateien umleiten:

cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null

Antwort2

Besitzen Sie zwei Wrapper-Skripte: Ändern Sie zunächst process_parallel.sh so, dass jeder der Prozesse angewiesen wird, seine Eingabe aus drei Dateien zu lesen, beispielsweise Datei1, Datei2, Datei3.

Schreiben Sie nun ein zweites Wrapper-Skript, das seine Standardeingabe parallel an die drei Dateien sendet, etwa so:

  #!/bins/bash
  #parallelise input
  # let's call this file parallelise
  parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3"

Jetzt fangen Sie an mit:

  ./process_parallel_sh; cat InputFile | parallelise; 

Antwort3

Parallel hat eine --teeOption, die wie folgt verwendet werden kann:

(sleep 1; echo "short input arriving late") |\
parallel --colsep ' ' --linebuffer --pipe --tee ::: 'python process1.py' ./process2.sh ./process3 |\
./collate_results.sh

SehenGNU „parallel“, wie man Abschlagverhalten erreicht

verwandte Informationen