私はプログラムを持っています./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
コマンドはオプションではないことに注意してください。
GNU xargs
:
seq 1000 | xargs -P4 -n1 sh -c 'exec ./pgm -a "file$1" -b 12 > "out.$1"' sh &
最大4つの./pgm
sを並行して実行します。
それ以外の場合は、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
を中断します(ksh93
とzsh
を除く)。
bash
以外のシェルでは、SIGCHLDハンドラーでジョブが開始されるアプローチを確認することもできます。
私も同じような問題を抱えていました。 parallel
はオプションではないと指定したので、 this の質問の回答で説明されているように、Swift
を調べる必要があるかもしれません。