我正在尝试以不同的方式并行处理输入,并在输入结果时写出它们。我当前的方法是这样的:
# 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
它将立即启动process1
、process2
和process3
。但是,输出可以混合,因此如果必须使用输出,则应将其重定向到不同的文件:
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