web-dev-qa-db-ja.com

シェルスクリプトでプロセスプールを作成できますか?

実行する必要のあるジョブが多数(数十または数百)あるが、それらは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ですが、一般的なソリューションまたは一般的なイディオムが望ましいでしょう。

2
user74422

GNU Parallelがある場合は、次のことができます。

parallel do_it {} --option foo < argumentlist

GNU Parallelは一般的な並列処理機能であり、同じマシンまたはsshにアクセスできる複数のマシンでジョブを簡単に並列実行できます。

4つのCPUで実行する32の異なるジョブがある場合、並列化する簡単な方法は、各CPUで8つのジョブを実行することです。

Simple scheduling

代わりに、GNU Parallelは、終了時に新しいプロセスを生成します。つまり、CPUをアクティブに保ち、時間を節約します。

GNU Parallel scheduling

インストール

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

5
Ole Tange

私はあなたとまったく同じ状況でしたが、並行して実行する必要のあるジョブは、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の方が適しているようです。

0
M.PG

できますが、それはトリッキーで壊れやすいものです。いくつかのオプションがあり、そのうちの1つはxargsです。

ジョブ制御とシグナルに依存するときに発生する問題については、この興味深い記事で説明されています。

http://prll.sourceforge.net/Shell_parallel.html

その男は、すべての入力と出力を同期する制御プロセスを使用する、任意のシェル関数を並行して実行できる(自動検出またはユーザー定義のプールサイズで)新しいツールprllを作成したようです。

ここでそれをチェックしてください: https://gitorious.org/prll/pages/Home

0
orion