在 Bash 中并行化循环

在 Bash 中并行化循环

我有一个 Bash 脚本,其中有一个循环来输入特定目录,并对特定输入文件进行一定的计算。之后,它从该目录退出,并在另一个目录中使用不同的输入文件执行相同的操作。计算需要很多时间,我想并行化它。

我如何修改我的脚本?有没有一个选项可以做到这一点?

myscript.sh

cd MainDir
for dir in *
  do
      cd ${dir}
      LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
     cd .. 
  done

我使用命令-cpu来指示cpu的使用情况。我有很多 CPU 可供使用,那么如何并行处理更多作业呢?

例如,如果我有三个不同的输入文件,我想一起运行(在不同的目录中)以下命令:

cd 1
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/1.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 1_res > 1_WPA.log
-----------
cd 2
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/2.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 2_res > 2_WPA.log
-----------
cd 3
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/3.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 3_res > 3_WPA.log

有人可以帮我吗?谢谢。

答案1

您可以在命令末尾添加&,将其发送到后台:

for i in 1 2 3 4; do
    (
        cd dir
        command
        [...]
    ) &
done
wait # pause until all background processes are terminated

答案2

zsh

do-calc() (
  cd -- $1 &&
    LD_LIBRARY_PATH=$software/ $software/calc \
      -i /home/files/$1.txt \
      -l /home/Str/Art.pdb \
      -a 5.0 \
      -rf /home/file/prot -cpu 1 opt -w ${1}_res > ${1}_WPA.log
)

autoload zargs
cd MainDir && zargs -rn1 -P12 -- ./*(N-/) -- do-calc

并行运行最多 12 个这些do-calc函数。

对于任何具有进程替换支持的类似 Korn 的 shell(例如 bash——GNU shell)和 GNU 实用程序,您可以执行类似的操作:

export software
cd MainDir &&
  xargs -0rn1 -P12 -a <(
      LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
        sort -z
    ) sh -c '
      cd -- "$1" &&
        LD_LIBRARY_PATH="$software/" "$software/calc" \
          -i "/home/files/$1.txt" \
          -l /home/Str/Art.pdb \
          -a 5.0 \
          -rf /home/file/prot -cpu 1 opt -w "${1}_res" > "${1}_WPA.log"
      ' sh

答案3

使用 GNU Parallel 你会做类似的事情:

doit() {
      dir="$1"
      cd ${dir}
      LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
}
export -f doit

cd MainDir
parallel doit  ::: *

这将为每个 CPU 线程运行一个作业。如果您不喜欢这样,您可以将其调整为并行运行 13 个作业:

parallel -j13 doit  ::: *

如果您有类似“:::”的文件,您需要执行以下操作:

LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
  parallel -0 doit

或者:

parallel --argsep /// -j13 doit  /// *

相关内容