バッチの多重起動の制御についてです。
色々方法はあるのでまとめようと思います。
多重制御の方法について
ロックファイルを作る
ポピュラーな方法みたいです。
バッチ起動時にロックファイルを作成し、実行完了したらロックファイルを削除する。
もし処理中にバッチが起動した場合、ロックファイルが存在するのでエラーにします。
しかしこの方法では、サーバーがダウンしたり、サーバーの再起動など、プログラムが強制終了したタイミングでロックファイルが残ってしまいます。
ロックファイルの制御について
ロックファイルの制御ですが、
- ロックファイルのタイムスタンプを確認し、古いものは削除して実行する
- ロックファイルにプロセスを残し、プロセスが一致しない場合は削除して実行する
などの選択があります。
アドバイザリロックでプロセスの多重起動を防止する
アドバイザリロックを簡単に説明すると、実行するプログラムファイルそのものをロックします。
こっちの方法ならロックファイルを作らなくても直接ファイル自体をロックして制御できるのでおススメです。
if ($this->checkLockFile() === false)
{
return;
}
$pid = getmypid();
echo "pid $pid\n";
echo "wait 10 sec ";
for ($i=0; $i<10; $i++)
{
sleep(1);
echo ".";
}
echo "\n";
exit;
/**
* Undocumented function
* @return void
*/
private function checkLockFile()
{
static $fp;
// ロックするファイル
$fp = fopen(__FILE__, "r");
// ファイルが有効かどうかチェック
if (is_resource($fp) == false)
{
throw new \RuntimeException("unable open [" . __FILE__ . ']');
}
$wouldBlock = false;
// ロックをかける
// 「LOCK_EX」は排他ロック
// 「LOCK_NB」を設定しないと、ロックが解除されるまで待つ
{
// ロックがかかっている場合、falseを返す
if ($wouldBlock)
{
return false;
}
throw new \RuntimeException("unable lock [" . __FILE__ . ']');
}
return true;
}