2

実行するジョブがたくさんあります。100 としましょう。それらは並列に実行できますが、それぞれが多くのメモリを消費するため、同時に実行できるのは 8 つだけです。

私は現在、このシェルスクリプトを持っています:

(
(python run.py $arg1 &)
(python run.py $arg2 &)
(python run.py $arg3 &)
(python run.py $arg4 &)
(python run.py $arg5 &)
(python run.py $arg6 &)
(python run.py $arg7 &)
(python run.py $arg8 &)
) 2>&1 | cat -u

(
(python run.py $arg9 &)
(python run.py $arg10 &)
(python run.py $arg11 &)
(python run.py $arg12 &)
(python run.py $arg13 &)
(python run.py $arg14 &)
(python run.py $arg15 &)
(python run.py $arg16 &)
) 2>&1 | cat -u

...

これには、最初の 8 個のバッチを実行する効果があり、それらがすべて終了すると、次の 8 個のバッチが開始されます。 8 の中で最も遅いものが完了するのを効果的に待っているため、8 の各バッチが終了するのを重み付けするのは最適ではありません。

代わりに、100 個のジョブすべてを実行するスクリプト (シェルまたは Python) を用意し、最適な効率のために、いつでも 8 個のジョブを同時に実行できるようにしたいと考えています。

それを達成するためのアイデアはありますか?

4

4 に答える 4

5

独自の小さなスケジューラを作成して、現在の割り当てが完了したプロセッサにそれらを分割できます。しかし、私たちのセンターでは、xargs のような構文で既に実装されているgnu parallelを使用することを強くお勧めします。

たとえば、上記のように、次のことができます

parallel --max-procs 8 <<EOF
  python run.py $arg1 
  python run.py $arg2 
  python run.py $arg3
  ..
EOF

または、ファイルに引数リストがある場合は、次のようにすることができます

cat args.list | parallel --max-procs 8 python run.py
于 2012-11-10T19:41:31.070 に答える
4

必要に応じて、多くのツールを使用できます。最も単純なのは、おそらく を使用することGNU parallelです。makeスイッチと並行してタスクを実行できます-j。実行しようとするタスクがより複雑で多様な場合は、Dr. Queueなどの実際のキュー システムが役立つ場合があります。他にも多くのツールがあり、GNU parallel の man ページにそれらがうまくリストされています。

于 2012-11-10T19:38:10.930 に答える
3

multiprocessingモジュール、具体的には を探しているようですmultiprocessing.Pool

私がこれを行っていた場合、すべての異なる引数セットを run.py に渡し、今トップレベルで実行していることをmain(args)関数内の run.py でラップし、Pool の map メソッドを使用してそのメソッドをすべてのオブジェクトに対して呼び出します。さまざまな引数のセット。

次のようになります。

import multiprocessing

def main(args):
  # Here's where you would do what you usually do with the arguments

pool = multiprocessing.Pool(processes=8)
pool.map(main, sys.argv[1:], chunksize=1)
pool.close()
pool.join()

これは、各実行の引数を 1 つの文字列 (したがって の 1 つのエントリ) に保持できると想定していることに注意してくださいsys.argv

于 2012-11-10T19:54:36.820 に答える