2009-07-14 103 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锁定。如果您发现以后需要,仍然可以锁定写入。我会尽快进一步释放锁,否则其他进程将不必要地阻塞。

相关问题