実行する必要のあるジョブが多数(数十または数百)あるが、それらはCPUに負荷がかかり、一度に実行できるのはごくわずかであるとします。 X
ジョブを一度に実行し、終了したら新しいジョブを開始する簡単な方法はありますか?私が思いつくことができる唯一のものは、以下のようなものです(擬似コード):
jobs=(...);
MAX_JOBS=4;
cur_jobs=0;
pids=(); # hash/associative array
while (jobs); do
while (cur_jobs < MAX_JOBS); do
pop and spawn job and store PID and anything else needed;
cur_jobs++;
done
sleep 5;
for each PID:
if no longer active; then
remove PID;
cur_jobs--;
done
よくあることですが、ソリューションを複雑にしすぎているように感じます。すべてのハードワークを実行するポートがある場合、ターゲットシステムはFreeBSDですが、一般的なソリューションまたは一般的なイディオムが望ましいでしょう。
GNU Parallelがある場合は、次のことができます。
parallel do_it {} --option foo < argumentlist
GNU Parallelは一般的な並列処理機能であり、同じマシンまたはsshにアクセスできる複数のマシンでジョブを簡単に並列実行できます。
4つのCPUで実行する32の異なるジョブがある場合、並列化する簡単な方法は、各CPUで8つのジョブを実行することです。
代わりに、GNU Parallelは、終了時に新しいプロセスを生成します。つまり、CPUをアクティブに保ち、時間を節約します。
インストール
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
私はあなたとまったく同じ状況でしたが、並行して実行する必要のあるジョブは、Rubyスクリプトを実行するコマンドです。最初に、完全ではなく、壊れやすいことを認める必要があります。
私がRubyコードでしたことは、
counting_process = IO.popen "ps -e | grep 'YourCMDPattern' -c"
count_of_processes = counting_process.readlines[0].to_i
次に、whileループで、プロセスの数を定期的にチェックし、シェルコマンドをトリガーして、数が保持したい並列実行の数を下回ったときに、RubyのIO.popenで特定の数の新しいプロセスを実行します。
実行する必要のあるシェルコマンドは動的であり、Rubyコードから生成された変数が含まれているため、Rubyスクリプトで実行する必要があります。
Rubyが関係していない場合は、GNUParallelの方が適しているようです。
できますが、それはトリッキーで壊れやすいものです。いくつかのオプションがあり、そのうちの1つはxargs
です。
ジョブ制御とシグナルに依存するときに発生する問題については、この興味深い記事で説明されています。
http://prll.sourceforge.net/Shell_parallel.html
その男は、すべての入力と出力を同期する制御プロセスを使用する、任意のシェル関数を並行して実行できる(自動検出またはユーザー定義のプールサイズで)新しいツールprll
を作成したようです。
ここでそれをチェックしてください: https://gitorious.org/prll/pages/Home