2009-07-14 84 views
-1

我使用文件系統來創建一個應用程序範圍的持久單例(應用程序不使用數據庫)。偶爾一個頁面需要1-2分鐘才能加載,而我已經將問題縮小到在獲取單例實例的函數中使用flock。下面是代碼的簡化版本:(編輯:在我原來的職位留給了代碼的最重要的部分)爲什麼在Windows/NTFS上偶爾需要花很長時間?

public static final function getInstance() { 
    if (is_null(self::$instance) { 
    $fh = fopen($filename, 'ab+'); 
    if (flock($fh, LOCK_EX)) { 
     $N = filesize($filename); 
     if ($N > 0) { 
     rewind($fh); 
     $s = stream_get_contents($fh); 
     $obj = unserialize($s); 
     } else { 
     $obj = new MyClass(); 
     } 
     self::$instance = $obj; 
     return $obj; 
    } else { 
     fclose($fh); 
     trigger_error("could not create lock", E_USER_WARNING); 
    } 
    } else { 
    return self::$instance; 
    } 
} 

的代碼,目前正在運行它使用XP和NTFS我的機器。
鎖始終被創建(即不調用trigger_error)。
延遲是隨機的,但在刷新命中時似乎更頻繁發生。
徹底擺脫雞羣可以消除問題,但也會使代碼不安全。

有什麼建議嗎?

有誰知道創建一個應用程序範圍持久性單例的更好方法嗎?

回答

1

誰關閉if {}子句中的$ fh?它不是敞開的嗎?在這種情況下,解鎖可能需要很長時間。 否則它至少會在腳本持續時間內掛起。

+0

將對象序列化回析構函數中的文件後關閉。 – 2009-07-14 14:21:28

0

您可以嘗試使用LOCK_SH參數而不是LOCK_EX鎖定。如果您發現以後需要,仍然可以鎖定寫入。我會盡快進一步釋放鎖,否則其他進程將不必要地阻塞。

相關問題