2012-01-05 74 views
2

我在運行Windows XP SP3和Apache 2.2.21的Web服務器上使用PHP 5.3.8,我需要創建一個互斥鎖。經過一番研究,我已經遇到了flock命令像這樣實現的:互斥與PHP 5.3.8

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()調用直到資源可用。

感謝, PaulH

+0

你在'Destroy'中有'if(is_resource($ this-> lock _))';''看起來不應該有分號。另外,如果您使用的是PHP5(並且您應該)考慮使用'__construct'和'__destruct' PHP魔術方法,而不是'Initialize'和'Destroy'。 – 2013-10-12 21:03:57

回答

4

調用flock()兩次在同一個文件句柄將返回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 
+0

正是我想要的行爲。非常感謝你。 – PaulH 2012-01-05 15:48:30