symfony1.4のプロセスで複数回実行されないようにする方法が必要です。
次のようなものです。ユーザーがこのプロセスを実行している場合、このプロセスを実行しようとする他のユーザーは、プロセスが実行中であることを通知する警告メッセージを受け取ります。
データベースを使用せずに実装する方法はありますか?
symfony1.4のプロセスで複数回実行されないようにする方法が必要です。
次のようなものです。ユーザーがこのプロセスを実行している場合、このプロセスを実行しようとする他のユーザーは、プロセスが実行中であることを通知する警告メッセージを受け取ります。
データベースを使用せずに実装する方法はありますか?
kiruganの方法はおそらくほとんどの場合に機能しますが、競合状態の影響を受けやすく、クラッシュが発生した場合にスタックする可能性があります。
これがより堅牢なソリューションです。PHPのファイルロックを使用しているため、ロックがアトミックであることがわかります。後でロックを解放するのを忘れたり、プロセスがクラッシュしたりすると、自動的に解放されます。デフォルトでは、ロックの取得は非ブロッキングです(つまり、ロックが別のプロセスによってすでに保持されている場合は、getLock()
即座にFALSEが返されます)。ただし、必要に応じて、呼び出しブロックを設定できます(つまり、ロックが使用可能になるまで待機します)。最後に、コードのさまざまな部分にさまざまなロックを設定できます。ロックには別の名前を使用してください。
唯一の要件は、によって返されるディレクトリgetLockDir()
がサーバー書き込み可能でなければならないということです。ロックディレクトリの場所を自由に変更してください。
注:flock()はWindows(私はLinuxを使用しています)では動作が異なる可能性があると思いますので、問題があるかどうかを再確認してください。
myLock.class.php
class myLock
{
/**
* Creates a lockfile and acquires an exclusive lock on it.
*
* @param string $filename The name of the lockfile.
* @param boolean $blocking Block until lock becomes available (default: don't block, just fail)
* @return mixed Returns the lockfile, or FALSE if a lock could not be acquired.
*/
public static function getLock($name, $blocking = false)
{
$filename = static::getLockDir() . '/' . $name;
if (!preg_match('/\.lo?ck$/', $filename))
{
$filename .= '.lck';
}
if (!file_exists($filename))
{
file_put_contents($filename, '');
chmod($filename, 0777); // if the file cant be opened for writing later, getting the lock will fail
}
$lockFile = fopen($filename, 'w+');
if (!flock($lockFile, $blocking ? LOCK_EX : LOCK_EX|LOCK_NB))
{
fclose($lockFile);
return false;
}
return $lockFile;
}
/**
* Free a lock.
*
* @param resource $lockFile
*/
public static function freeLock($lockFile)
{
if ($lockFile)
{
flock($lockFile, LOCK_UN);
fclose($lockFile);
}
}
public static function getLockDir()
{
return sfConfig::get('sf_root_dir') . '/data/lock';
}
}
使い方
$lockFile = myLock::getLock('lock-name');
if ($lockFile) {
// you have a lock here, do whatever you want
myLock::freeLock($lockFile);
}
else {
// you could not get the lock. show a message or throw an exception or whatever
}
これが私の関数です:
function lock(){
$file = __DIR__ . '/file.lock';
if(file_exists($file)){
/* exit or whatever you want */
die('ALREADY LOCKED');
}
touch($file);
}
function unlock(){
$file = __DIR__ . '/parser.lock';
if(file_exists($file)){
unlink($file);
}else{
echoln("unlock function: LOCK FILE NOT FOUND");
}
}
function exitHandler(){
echoln('exitHandler function: called');
unlock();
}
lock
最初に関数を使用し、でexitHandler
関数を設定しregister_shutdown_function()
ます。このスニペットを同じメソッドでクラスとして保存することも、ヘルパーファイルのように保存することもできます