gnu並行:將所有stdin轉送到所有行程

gnu並行:將所有stdin轉送到所有行程

我正在嘗試以不同的方式並行處理輸入,在輸入結果時寫出結果行。

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

上下文可以歸結為這樣:

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

上述方法有效,但有一個重要的缺點:在讀取輸入之前,進程不會啟動。我想立即啟動它們,因為這可能需要一段時間,然後將其完整的標準輸入並行管道傳輸到它們中的每一個。

我該如何實現這個目標?

答案1

GNU Parallel 已投入大量工作,使其在沒有資料可運行時不會啟動新作業。這是由於某些程式如果沒有得到任何輸入就會嚴重失敗。所以你將違背 GNU Parallel 的設計。

要複製輸入,您可以使用tee並處理替換:

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

它將立即開始process1process2process3。但是,輸出可以混合,因此如果必須使用輸出,您應該將其重定向到不同的檔案:

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

答案2

有兩個包裝器腳本:首先,修改 process_parallel.sh,以便指示每個進程從三個檔案(例如 file1、file2、file3)讀取其輸入。

現在編寫第二個包裝器腳本,它將其標準輸入並行發送到三個文件,如下所示:

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

現在你開始你的事情:

  ./process_parallel_sh; cat InputFile | parallelise; 

答案3

Parallel 有一個--tee選項,可以這樣使用:

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

GNU「並行」如何實現tee行為

相關內容