gnu parallel:将所有 stdin 转发到所有进程

gnu parallel:将所有 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行为

相关内容