Ein*_*nar 11 parallel-processing bash gnu-parallel
我在Bash中有一个while循环处理如下:
while IFS=$'\t' read -r -a line;
do
myprogram ${line[0]} ${line[1]} ${line[0]}_vs_${line[1]}.result;
done < fileinput
Run Code Online (Sandbox Code Playgroud)
它从具有此结构的文件中读取,以供参考:
foo bar
baz foobar
Run Code Online (Sandbox Code Playgroud)
等等(制表符分隔).
我想使用GNU parallel并行化这个循环(因为条目很多,处理速度很慢),但是我不知道如何将每一行分配给数组,就像我在这里做的那样.
什么是可能的解决方案(GNU并行工作的替代方案)?
来自https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Use-a-table-as-input:
msgstr"""
table_file.tsv的内容:
foo<TAB>bar
baz <TAB> quux
Run Code Online (Sandbox Code Playgroud)
跑步:
cmd -o bar -i foo
cmd -o quux -i baz
Run Code Online (Sandbox Code Playgroud)
你可以运行:
parallel -a table_file.tsv --colsep '\t' cmd -o {2} -i {1}
Run Code Online (Sandbox Code Playgroud)
"""
所以在你的情况下它将是:
cat fileinput | parallel --colsep '\t' myprogram {1} {2} {1}_vs_{2}.result
Run Code Online (Sandbox Code Playgroud)
我想要@chepner hack。而且,通过限制并行执行次数来完成类似的行为似乎并不那么棘手:
while IFS=$'\t' read -r f1 f2;
do
myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" &
# At most as number of CPU cores
[ $( jobs | wc -l ) -ge $( nproc ) ] && wait
done < fileinput
wait
Run Code Online (Sandbox Code Playgroud)
它限制了系统上存在的最大CPU内核数的执行。您可以通过替换$( nproc )为所需数量来轻松地改变它。
同时,您应该了解什么不是诚实的分配。因此,它不会在一个线程完成后立即启动新线程。相反,它只在开始最大数量后才等待全部完成。因此,汇总吞吐量可能会略低于并行吞吐量。特别是如果您的程序的运行时间可能在较大范围内变化。如果花费在每次调用上的时间几乎相同,那么摘要时间也应该大致相等。
parallel这里不是绝对必要的;只需在后台启动所有进程,然后等待它们完成即可。该数组也是不必要的,因为您可以提供read多个变量来填充:
while IFS=$'\t' read -r f1 f2;
do
myprogram "$f1" "$f2" "${f1}_vs_${f2}.result" &
done < fileinput
wait
Run Code Online (Sandbox Code Playgroud)
这确实为列表中的每个项目启动了一个作业,而parallel可以限制一次运行的作业数量。您可以在 中完成相同的操作bash,但这很棘手。