web-dev-qa-db-ja.com

使用可能なCPUを考慮して、制御下で複数の「シリアル」プロセスを実行する方法は?

Maaaaaaaaanyファイルで実行する必要のあるバイナリがあるとします(ファイルの番号は1からNであると仮定します)。各ファイルは、このバイナリを呼び出すことによって処理する必要があります(たとえば、md5sumのようなもの)。実行するたびに、結果が別々のファイルに保存されます。つまり、1000個のファイルがあり、CPUが4個しかない場合、次のようなことはしたくありません(可能な場合は、実際には)。

i=0; while [ $i -lt 1000 ]; do md5sum a_file_$i > result_$i & i=$(( $i + 1 )); done

なぜなら(bashが文句を言わなくても)、コンピューターをクロールモードにする1000のプロセスを開始することになるからです。

一度にn個のプロセスのように実行する必要があることをコマンドに伝えることができるコマンドを使用できますか(n個のプロセスを開始し、プロセスが終了するタイミングを監視してから、プロセスの数が増えるように別のプロセスを開始します実行中は常にn)?

1
eftshift0

GNU parallel はあなたが探しているツールです。著者 Ole Tange はここでは常連であり、 それについての質問 にいくつかの良い答えを書いています。

GNUバージョンのxargsからfindutilsには、複数のジョブを並行して実行するためのオプションもいくつかあります。おそらくあなたのような単純な仕事に使用する方が簡単ですが、parallelほど柔軟で有能ではありません。

例えば:

find . -maxdepth 1 -type f -name 'a_file_*' -print0 | 
  xargs -0r -L 1 -P 4 sh -c '/usr/bin/md5sum "$1" > "$1.md5sum"' {}

これは、最大4 md5sumジョブを並行して実行します(-P 4)。また、-L 1オプションを使用して、各ジョブを一度に1つのファイル名の処理に制限しました-それがないと(そうでない場合は、1000のファイル名で1つのジョブしか実行されません)

2
cas