GNUシステムでは、もしあればpv
、次のことができます:
cmd='
that command | to execute &&
as shell code'
yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
-P20
ほとんどの20で実行することである$cmd
と同時に。
-L10
レートを1秒あたり10バイトに制限しているため、1秒あたり5行です。
あなたの場合$cmd
、sは2遅くなると到達する20の限界を起こし、その後、xargs
1つのまで読み取りを停止します$cmd
少なくともリターンでインスタンス。pv
パイプがいっぱいになるまで、同じ速度でパイプへの書き込みを続けます(デフォルトのパイプサイズが64KiBのLinuxでは、ほぼ2時間かかります)。
その時点で、pv
書き込みを停止します。しかし、それでも、xargs
読み取りを再開pv
すると、全体で1秒あたり5行を維持するために、できるだけ早く送信する必要があるすべての行を追いつき、送信しようとします。
つまり、平均的な要件で1秒あたり5回の実行を20プロセスで実行できる限り、それを実行します。ただし、制限に達すると、新しいプロセスが開始される速度はpvのタイマーではなく、以前のcmdインスタンスが戻る速度によって決まります。たとえば、20が現在実行中で10秒間使用されていて、そのうちの10がすべて同時に終了することを決定した場合、10の新しいものが同時に開始されます。
例:
$ cmd='date +%T.%N; exec sleep 2'
$ yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
09:49:23.347013486
09:49:23.527446830
09:49:23.707591664
09:49:23.888182485
09:49:24.068257018
09:49:24.338570865
09:49:24.518963491
09:49:24.699206647
09:49:24.879722328
09:49:25.149988152
09:49:25.330095169
2つの実行間の遅延が常に正確に0.2秒であるとは限らない場合でも、平均で1秒あたり5回になります。
With ksh93
(またはコマンドが小数秒をサポートするzsh
場合sleep
):
typeset -F SECONDS=0
n=0; while true; do
your-command &
sleep "$((++n * 0.2 - SECONDS))"
done
your-command
ただし、同時sの数に制限はありません。