Bash:固定数のプロセスを待ちます。

Bash:固定数のプロセスを待ちます。

Java jarを実行するbashスクリプトを作成しました。N頻度。

実際に私はeを定義します。金持ち()通話を含む機能できるその後、このスクリプトを実行します。

for RUN in $(seq 1 $RUNS) 
do 
    foo & 
done

今処刑したくない走る並列時間できる。並列実行数に待機制限があります(例:wait10プロセスごと)。

答え1

bashバージョン 4.4 では、次の便利な新しいイディオムが導入されました。パラメータ変換この場合は役に立ちます。以下のコードスニペットでは、${num_jobs@P}これは@P型であることに注意してください。パラメータ変換これにより、変数はプロンプト文字列のように拡張されますbashman 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

Cheppnerのクレジットhttps://stackoverflow.com/a/38775799/6631810


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

答え2

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

10の倍数でない場合は、waitループの後に別の値を追加することもできます。$RUNS


RUNS合計実行回数に加えて、n10のジョブ配置を想像することもできます。

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があるコマンドライン引数(生成された整数の1つ)を提供します。seqこれにより問題が解決します。

seq 1 "$RUNS" | xargs -n 1 -P 10 sh -c 'foo'

答え3

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並列スケジューリング

インストールする

セキュリティ上の理由から、パッケージマネージャを使用して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

関連情報