8

システムに保存されているファイルを並行して検索するためにGNU Parallelを使用できるかどうかを評価しています。システムには、1 年のうち 1 日 (doy) ごとに 1 つのファイルしか存在できません (したがって、1 年あたり最大 366 ファイル)。システムに 3660 個のファイル (約 10 年分のデータ) があるとします。システムは、マルチ CPU マルチコア Linux またはマルチ CPU Solaris である可能性があります。

ファイルに対して実行する検索コマンドを配列に格納しています (ファイルごとに 1 つのコマンド)。そして、これは私が現在行っていることです(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(最大 CPU/コアを自動的に計算し、非常に多くの検索のみを並行して開始します)、配列cmdsを並行して再利用し、上記のコードを書き直すにはどうすればよいですか? もう 1 つの方法は、すべてのコマンドをファイルに書き込んでから実行することです。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- as-mutex-and-counting-semaphore

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 に答える