はじめに
Bashでコマンドの同時実行数を一定時間中維持したいということがあり作成したところ、
汎用性がありそうだったので備忘録として残します。
方法について
以下の二通りのコードを作成しました。
コマンドの終了時間が同じ場合
#! /bin/bash
# 同時実行数
concurrent_commands=10
# 実行時間
duration_seconds=10
# 実行するコマンド
command="sleep 1"
run_command() {
$command &
}
concurrent_run() {
# 現在時刻をエポック秒で取得し、指定された秒数を加算
end=$(( $(date +%s) + duration_seconds ))
(
# 一定時間中ループを繰り返す
while [ "$(date +%s)" -lt $end ]; do
# 指定された同時実行数のコマンドを一斉に実行
for ((i=0; i<concurrent_commands; i++)); do
run_command
done
# 実行されたコマンドの終了を待機
wait
done
) &
# 強制終了された時にバッググラウンドの処理を終了
local pid=$!
trap 'kill $pid; exit 1' 1 2 3 15
wait
}
concurrent_run
コマンドの終了時間がバラバラな場合
concurrent_commands=10
duration_seconds=10
command="sleep"
run_command() {
$command $(( RANDOM % 10 + 1 )) &
}
concurrent_run() {
# 現在時刻をエポック秒で取得し、指定された秒数を加算
end=$(( $(date +%s) + duration_seconds ))
(
# 指定された同時実行数のコマンドを一斉に実行
for ((i=0; i<concurrent_commands; i++)); do
run_command
done
# 一定時間中ループを繰り返す
while [ "$(date +%s)" -lt $end ]; do
# 現在の実行数を取得
running_jobs=$(jobs -p | wc -l)
# 現在の実行数が指定された同時実行数を下回っていたらコマンドを実行
if [ "$running_jobs" -lt "$concurrent_commands" ]; then
run_command
fi
sleep 0.1
done
) &
local pid=$!
trap 'kill $pid; exit 1' 1 2 3 15
wait
}
concurrent_run
例としてsleepを使っていますが、実行したい任意のコマンドに変更してください。
以上です。
さいごに
誰かのお役にたてれば幸いです。