ファイルシステムを使用して、アプリケーション全体で永続的なシングルトン(アプリケーションはデータベースを使用しない)を作成します。場合によってはページをロードするのに1〜2分かかることがあり、シングルトンのインスタンスを取得する関数でflockを使用するように問題を絞り込んでいます。 (編集:私のオリジナルのポスト内のコードの最も重要な部分を残し)Windows/NTFSでflockに時折時間がかかるのはなぜですか?
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は呼び出されません)。
遅延はランダムですが、リフレッシュがヒットした場合に発生するように見えます。
群を排除すると、問題は完全に解消されますが、コードが安全でなくなります。
アドバイスはありますか?
誰もがアプリケーション全体の永続シングルトンを作成する良い方法を知っていますか?
オブジェクトがデストラクタのファイルにシリアル化された後、そのオブジェクトが閉じられた後に閉じられます。 –
これは間違いありません。コードスニペットによれば、ファイル記述子$ fhはgetInstance()内でのみ有効です。ローカル変数であり、グローバルではなく、getInstancde()で "生き残る"別の参照を格納するコードはありません。私。それは、PHPのメソッドのスコープを離れるときに破壊されるはずです。その場合、php_stdiop_close($ fh、...)が呼び出されます。ファイルハンドルを閉じ、このストリームリソースに関連付けられているファイルロックも解放します。本当のコードを見せてくれましたか? – VolkerK