我在运行Windows XP SP3和Apache 2.2.21的Web服务器上使用PHP 5.3.8,我需要创建一个互斥锁。经过一些研究,我遇到了flock命令,并按照以下方式实现:
class Mutex
{
private $lock_ = null;
// create a mutex with with a given id. This ID must be system unique.
// [string] id - a unique id
// return - true on success
public function Initialize($id)
{
$this->lock_ = fopen($id, 'a');
return is_resource($this->lock_);
}
// destroy the mutex
public function Destroy()
{
$result = false;
if (is_resource($this->lock_));
{
$result = flock($this->lock_, LOCK_UN);
$result &= fclose($this->lock_);
$this->lock_ = null;
}
return $result;
}
// exclusively lock the resource
// return - true on success
public function Lock()
{
if (is_resource($this->lock_))
return flock($this->lock_, LOCK_EX);
return false;
}
// release the locked resource
// return - true on success
public function Release()
{
if (is_resource($this->lock_))
return flock($this->lock_, LOCK_UN);
return false;
}
}
但是,当我去使用这个课时:
$this->cache_lock_ = new Mutex();
$this->cache_lock_->Initialize("e:\\cache_lock");
if ($this->cache_lock_->Lock())
echo "Acquired 1 ".PHP_EOL;
if ($this->cache_lock_->Lock())
echo "Acquired 2 ".PHP_EOL;
$this->cache_lock_->Release();
$this->cache_lock_->Destroy();
我看到Acquired 1 Acquired 2
已打印,表明锁已被获取两次,尽管我指定它是独占的。
有人能说出我做错了吗?理想情况下,我希望第二个Lock()调用toblock直到资源可用。
谢谢, PaulH
答案 0 :(得分:5)
在同一个文件句柄上调用flock()两次将返回true并且不会阻塞,因为该函数检查文件句柄是否已被锁定,如果是,则返回true。这是预期的行为。但是,如果多个进程并行运行,它将按预期工作,因为每个进程将具有不同的文件句柄。如果要在单个进程中对此进行测试,请为同一文件对象创建多个句柄:
$a = new Mutex();
$a->Initialize("file.lock");
$a->Lock(); // this will simply lock the file object
$b = new Mutex();
$b->Initialize("file.lock");
$b->Lock(); // this will block, because the file is locked by $a