在執行來自 STDIN 的參數之前使 GNU Parallel 不延遲
沒有任何命令行選項的 GNU Parallel 允許您輕鬆地並行化其最後一個參數由一行 STDIN 確定的命令:
$ seq 3 | parallel echo 2 1 3
請注意,
parallel
在開始執行作業之前不要等待 STDIN 上的 EOF - 執行yes | parallel echo
將立即開始列印無限多個副本y
。但是,如果 STDIN 相對較短,這種行為似乎會發生變化:
$ { yes | ghead -n5; sleep 10; } | parallel echo
在這種情況下,完成前不會返回任何輸出
sleep 10
。這只是一個例子——實際上,我試圖從一系列連續生成的 FIFO 管道中讀取數據,在這些管道中,直到現有管道開始被消耗,FIFO 生成過程才會繼續。例如,我的命令將生成一個 STDOUT 流,如:
/var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.PFcggGR55i /var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.UCpTBzI3J6 /var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.r2EmSLW0t9 /var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.5TRNeeZLmt
在新終端中一次一個地手動
cat
輸入這些文件會導致 FIFO 生成過程成功完成。但是,跑步printfifos | parallel cat
不起作用。相反,parallel
似乎永遠阻塞等待 STDIN 上的輸入——如果我將管道修改為printfifos | head -n4 | parallel cat
,死鎖就會消失並且前四個管道被成功列印。這種行為似乎與
--jobs|-j
參數有關。雖然{ yes | ghead -n5; sleep 10; } | parallel cat
10 秒內沒有輸出,但添加一個-j1
選項會產生四行y
幾乎立即,然後等待 10 秒以等待最終的y
. 不幸的是,這並不能解決我的問題——我需要先處理每個參數,然後parallel
才能從讀取 STDIN 中獲取 EOF。有什麼辦法可以做到這一點?
GNU Parallel 中的一個錯誤是,它僅在為每個作業槽讀取一個作業後才開始處理。之後,它一次讀取一份作業。
在舊版本中,輸出也會因作業槽的數量而延遲。較新的版本僅延遲單個作業的輸出。
因此,如果您每秒發送一個作業,
parallel -j10
它將在開始之前讀取 10 個作業。在舊版本中,您必須再等待 10 秒才能看到作業 3 的輸出。開始時限制的一種解決方法是為每個作業槽提供一個虛擬作業以並行:
true >jobqueue; tail -n+0 -f jobqueue | parallel & seq $(parallel --number-of-threads) | parallel -N0 echo true >> jobqueue # now add the real jobs to jobqueue
輸出要使用的解決方法
--linebuffer
(但這將混合來自不同作業的完整行)。