7

次のように flock を使用している人を見かけます。

if (!$fp = fopen($file_name, 'wb'))  
{  
    return FALSE;  
}  

if (flock($fp, LOCK_EX))  
{  
    fwrite($fp, serialize($data));  
    flock($fp, LOCK_UN);  
}

これも:

if (!$fp = @fopen($file_name, 'rb'))  
{  
    return FALSE;  
}  

flock($fp, LOCK_SH);  

$data = '';  

if (filesize($file_name) > 0)  
{  
    $data = unserialize(fread($fp, filesize($file_name)));  
}  

fopenしかし、通話と通話の間に他の誰かがファイルを編集する可能性はありませんflockか? と同じ質問fread


編集:
なぜ私がこれを求めているのかを明確にするために...私は私の質問をここのコードに基づいています。 fopenとflockの間に入ることができますか?

そのコードは絶対確実ですか?

4

2 に答える 2

6

あなたが尋ねる:

fopen 呼び出しと flock 呼び出しの間に他の誰かがファイルを編集する可能性はありませんか? フレッドへの同じ質問

そうですね。簡単な答え: 「はい」と仮定して、慎重に行動してください。

はい、その伝統的な flock() ベースのロックは単なるアドバイザリであるため、他のプロセス (または同じプロセスでさえ) はロックを自由に無視できます。flock() は行儀の良いクライアント コードで使用されるため、実際にはこれは問題ではありません。特定のファイル。

いいえ、特定のオペレーティング システムでは PHP の flock() の実装が必須である可能性があり、ドキュメンテーションに従って、ファイル システムからのサポートも必要になる場合があります (たとえば、Linux でのmandオプションのように)。そのため、他のプロセスはそれらのロックを無視できませんでした。

おそらく、PHP 5 のストリーム サブシステムは、オペレーティング システムが提供する以上のロック ブックキーピングを実装しています。これにより、たとえば、同じプロセス (ただし、別のプロセスではない) がそれ自体のアドバイザリ ロックを無視するのを防ぐことができます。この振る舞いは、一部の人を驚かせるかもしれません。それでも、この種のロックは、無関係なプロセス間では必須ではありません。

移植性のために、最も弱いセマンティクス (上記の「はい」) を想定し、事前に選択されたアプリケーション固有のロックファイルで適切に動作するコードに flock()ing を制限します。

于 2012-08-05T20:55:56.527 に答える
2

最初のスニペットは絶対確実です。ファイルをロックできない場合は、書き込みを行いません。他の誰かがとの間fopen()でファイルを編集した場合、ファイルハンドルは、「スナップショット」ではなくストリームにバインドされるflock()ため、最新のインカネーションを指します。fopen()

2番目の例は、の戻り値がチェックされていないため、動作が保証されていflock()ません。したがって、ロックを取得していない場合は、とにかく後続のコードが実行されます。

[編集]以下のコメントで説明されているように、リーダーロックは重要ではないというステートメントを削除しました:)

于 2012-08-05T20:33:38.513 に答える