CentOS マシンの cron で数分ごとに実行するようにスケジュールされた多数の php スクリプトがあります。すべてのスクリプトで、開始時に以前のインスタンスがまだ実行されているかどうかを自己チェックし、実行されている場合は停止したいと思います。
4 に答える
タスクを管理し、一度に 1 つだけ実行するようにするためにこれを行います
public function startTask($taskname)
{
$running = "running";
$lockfile = $taskname . "RUNNING";
file_put_contents($lockfile, $running);
}
public function endTask($taskname)
{
$lockfile = $taskname . "RUNNING";
unlink($lockfile);
}
public function isTaskRunning($taskname)
{
$lockfile = $taskname . "RUNNING";
if (file_exists($lockfile))
{
return true;
}
}
startTask('name')
タスクの開始endTask('name')
時と完了時に電話します。そして、使用するタスクの最初の行で
if (isTaskRunning('name')) {
die('already running');
}
これらを構成クラスまたはすべてのタスク ファイルに含まれているものに入れて、離れてください。
ロック ファイルを使用します。
<?php
$lockfile = "/tmp/lock.txt";
$fp = fopen($lockfile, "r+");
if (flock($fp, LOCK_EX)) { // acquire an exclusive lock
ftruncate($fp, 0); // truncate file
fwrite($fp, sprintf("Started: %s\nPID: %s", date(), getmypid()));
// perform your tasks here.
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
} else {
echo "Couldn't get the lock!\nCheck $lockfile for more info.";
}
fclose($fp);
または、データベースを使用している場合は、次のNamed Lock
ようにデータベースを作成できます。
<?php
$process = "myProcess";
$sql = mysql_query("select get_lock('$process', 0)");
$got_lock = (bool)mysql_fetch_array($sql)[0];
// If process is already running exit
if(!$got_lock){
echo "Process running";
exit;
}
// Run my process
for($i=0;$i<100000000;$i++){
echo $i;
}
// Release the lock
mysql_query("select release_lock('$process')");
この形式のロックは と呼ばれnamed lock
、データベースを「ロック」するのではなく、単に「名前付きロック」を作成し、呼び出すと名前が存在するかどうかを確認します。table lock
またはのようなものではありませんrow lock
。このような他のアプリケーション用に mysql に組み込まれています。
ロックは必要なだけ持つことができ、クライアントが mysql から切断するなど、アプリケーションが終了すると自動的に解放されます: プロセスの終了、php の中断/クラッシュ、mysql のクラッシュ (これについては 100% 確実ではありません) など。
PHP スクリプトの最後に (おそらく date() を使用して) 簡単なエコーを追加できます。これは cron ログに表示され、スクリプトが最後に到達した (そしてタスクを終了した) かどうかを示します。