我需要一种方法来防止symfony 1.4上的进程多次运行。
类似于:当用户运行此进程时,尝试运行此进程的其他用户将收到一条警告消息,通知该进程正在运行。
有没有办法在不使用数据库的情况下实现它?
答案 0 :(得分:3)
这是一个更强大的解决方案。它使用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
}
答案 1 :(得分:1)
以下是我的功能:
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()
功能。您可以使用相同的方法将此片段保存为类,或者将其保存为辅助文件