8

我正在评估是否可以使用GNU Parallel来搜索并行存储在系统上的文件。系统上一年中的每一天 (doy) 只能有一个文件(因此每年最多 366 个文件)。假设系统上有 3660 个文件(大约 10 年的数据)。该系统可以是多 CPU 多核 Linux 或多 CPU Solaris。

我正在存储要在数组中的文件上运行的搜索命令(每个文件一个命令)。这就是我现在正在做的事情(使用 bash),但是我无法控制并行启动多少搜索(绝对不想一次启动所有 3660 搜索):

#!/usr/bin/env bash
declare -a cmds
declare -i cmd_ctr=0

while [[ <condition> ]]; do
    if [[ -s $cur_archive_path/log.${doy_ctr} ]]; then
      cmds[$cmd_ctr]="<cmd_to_run>"
      let cmd_ctr++
    fi
done

declare -i arr_len=${#cmds[@]}
for (( i=0; i<${arr_len}; i++ ));
do
  # Get the command and run it in background
  eval ${cmds[$i]} &
done
wait

如果我要使用parallel(它会自动计算出最大 CPUs/cores 并且只开始并行搜索这么多),我如何才能cmds并行重用数组并重写上面的代码?另一种选择是将所有命令写入文件,然后执行cat cmd_file | parallel

4

1 回答 1

9

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Using-shell-variables说:

parallel echo ::: "${V[@]}"

你不想要回声,所以:

parallel ::: "${cmds[@]}"

如果您不需要 $cmds 做其他任何事情,请使用“sem”(它是并行 --semaphore 的别名)https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-作为互斥量和计数信号量

while [[ <condition> ]]; do
  if [[ -s $cur_archive_path/log.${doy_ctr} ]]; then
    sem -j+0 <cmd_to_run>
  fi
done
sem --wait

您还没有描述 <condition> 可能是什么。如果您只是在执行类似 for 循环的操作,则可以将整个脚本替换为:

parallel 'if [ -s {} ] ; then cmd_to_run {}; fi' ::: $cur_archive_path/log.{1..3660}

(基于https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Composed-commands)。

于 2013-05-13T07:42:04.860 回答