Java jarをnの回数実行するbashスクリプトを作成しました。
実際には、jarの呼び出しを含むe foo()関数を定義してから、次のスクリプトを実行します。
for RUN in $(seq 1 $RUNS)
do
foo &
done
runs回jarを並列実行しないようにしたいと思います。並列実行の数を制限するための待機がありますか(たとえば、10プロセスごとにwait
のように)?
bash
バージョン4.4では、パラメータ変換と呼ばれる便利な新しいイディオムが導入され、この場合に役立ちます。以下のコードスニペットでは、${num_jobs@P}
の使用に注意してください。 @P
はパラメータ変換の一種であり、bash
プロンプト文字列であるかのように変数を展開します。その他のパラメータ変換オプションについては、man bash
を参照してください。
#!/bin/bash
num_procs=$1
num_iters=$2
num_jobs="\j" # The Prompt escape for number of jobs currently running
for ((i=0; i<num_iters; i++)); do
while (( ${num_jobs@P} >= num_procs )); do
wait -n
done
foo &
done
https://stackoverflow.com/a/38775799/663181 のchepnerへのクレジット。
Kusalanandaのコメントに従い、必要に応じて、このプロセスのグループを、カウントに影響を与える他のバックグラウンドジョブから独立させるために、独自のシェルでラップすることができます。このため、いくつかの変更が必要です。
#!/bin/bash
# start a wrapper Shell for the group of jobs
cat<<EOS | bash &
num_procs="$1"
num_iters="$2"
for ((i=0; i<num_iters; i++)); do
# escape what's not supposed to be expanded
# at the time of here-doc redirection
while (( \${num_jobs@P} >= num_procs )); do
wait -n
done
foo &
done
EOS
# now you can do other things
for RUN in $(seq 1 $RUNS); do
foo &
if (( (RUN % 10) == 0 )); then
wait
fi
done
または、代替のループ構造を使用して(見栄えの良いIMHO):
for (( r = 1; r <= RUNS; ++i )); do
foo &
if (( (r % 10) == 0 )); then
wait
fi
done
ループの後にwait
を追加したい場合は、$RUNS
は10の倍数ではありません。
実行する実行の総数としてRUNS
を使用する代わりに、10個のジョブのn
バッチを使用することもできます。
for (( i = 0; i < n; ++i )); do
printf 'starting batch %d...\n' "$i"
for (( j = 0; j < 10; ++j )); do
foo &
done
echo 'waiting...'
wait
done
xargs
を使用し、明示的なwait
を使用しない代替ソリューション:
seq 1 "$RUNS" | xargs -n 1 -P 10 foo
ただし、これはfoo
プロセスに不要なコマンドライン引数(seq
によって生成される整数の1つ)を与えることになります。これはその問題を取り除きます:
seq 1 "$RUNS" | xargs -n 1 -P 10 sh -c 'foo'
GNU Parallelはまさにこれのために作られています:
seq 1 $RUNS | parallel -j 10 -N0 foo
デフォルトでは、CPUコアごとに1つのジョブを実行します。
seq 1 $RUNS | parallel -N0 foo
GNU Parallelは、一般的なパラレライザーであり、同じマシン上で、またはsshにアクセスできる複数のマシン上で、ジョブを簡単に並列実行できます。
4つのCPUで実行する32の異なるジョブがある場合、並列化する簡単な方法は、各CPUで8つのジョブを実行することです。
代わりに、GNU Parallelは、プロセスが終了すると新しいプロセスを生成します-CPUをアクティブに保ち、時間を節約します。
インストール
セキュリティ上の理由から、パッケージマネージャとGNU Parallelをインストールする必要がありますが、GNU Parallelがディストリビューションにパッケージ化されていない場合は、個人用インストールを実行できます。 rootアクセスは必要ありません。これを行うと、10秒で実行できます。
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
他のインストールオプションについては http://git.savannah.gnu.org/cgit/parallel.git/tree/README を参照してください
詳細
その他の例を見る: http://www.gnu.org/software/parallel/man.html
紹介ビデオを見る: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
チュートリアルをご覧ください: http://www.gnu.org/software/parallel/parallel_tutorial.html
サポートを受けるには、メーリングリストにサインアップしてください: https://lists.gnu.org/mailman/listinfo/parallel