web-dev-qa-db-ja.com

並列実行バックグラウンド

私はプログラムを持っています./pgmいくつかの引数を取る(たとえば-a file1 -b val)、実行には2秒かかります。自分のマシンのすべてのプロセッサを使用して、このプログラムをすべての入力ファイル(約1000)で並行して実行したいと思います。私が今していることは、すべてのコマンドを置くことです

./pgm -a file1 -b 12 > out1.txt &
./pgm -a file2 -b 14 > out2.txt &
./pgm -a file3 -b 16 > out3.txt &
./pgm -a file4 -b 18 > out4.txt &
...

ファイルに入れて、このファイルを実行します。これは利用可能なすべてのプロセッサを使用すると思いましたが、並列実行の数は非常に限られています。

どうすればこれを達成できますか? parallelコマンドはオプションではないことに注意してください。

2
wwjoze

GNU xargs

seq 1000 | xargs -P4 -n1  sh -c 'exec ./pgm -a "file$1" -b 12 > "out.$1"' sh &

最大4つの./pgmsを並行して実行します。

それ以外の場合は、pdksh/mksh/oksh

trap : CHLD
n=0
for f in file*; do
  jobs=$(jobs | wc -l)
  if (($jobs < 4)); then
    ./pgm "$f" > out.$((++n)) &
  else
    wait
  fi
done
trap - CHLD
wait

信号処理の詳細は、シェルごとに異なります。そのトリックはpdkshとその派生物では機能しますが、私が試した他のシェルでは機能しません。 SIGCHLDをトラップできるシェル(bashを除く)が必要です。ここで、SIGCHLDハンドラーはすぐに実行されます(wait中にブロックされません)(ashを除く)- yash )、ここでSIGCHLD処理はwaitを中断します(ksh93zshを除く)。

bash以外のシェルでは、SIGCHLDハンドラーでジョブが開始されるアプローチを確認することもできます。

5

私も同じような問題を抱えていました。 parallelはオプションではないと指定したので、 this の質問の回答で説明されているように、Swiftを調べる必要があるかもしれません。

1
Ramesh