ホームページ  >  記事  >  バックエンド開発  >  phpファイルロック(転送)

phpファイルロック(転送)

WBOY
WBOYオリジナル
2016-06-23 14:31:28854ブラウズ

bool flock ( int handle, int Operation [, int &wouldblock] );
flock() 操作のハンドルは、開いているファイル ポインターである必要があります。操作は次の値のいずれかになります:

共有ロック (リーダー) を取得するには、操作を LOCK_SH に設定します (PHP 4.0.1 より前のバージョンでは 1 に設定します) 排他的ロック (ライター) を取得するには、操作を LOCK_EX (ロック (共有か排他かに関係なく) を解放するには、操作を LOCK_UN に設定します (PHP 4.0.1 より前のバージョンでは 3 に設定)。 flock() を If に設定したくない場合は、ロック中はブロックされるため、操作に LOCK_NB を追加します (PHP 4.0.1 より前のバージョンでは 4 に設定)

2 つのファイルを作成
(1) a.php

$file = "temp.txt";    $fp = fopen($file , 'w');    if(flock($fp , LOCK_EX)){         fwrite($fp , "abc\n");         sleep(10);         fwrite($fp , "123\n");        flock($fp , LOCK_UN);    }    fclose($fp);   

(2) b.php

$file = "temp.txt";    $fp = fopen($file , 'r');    echo fread($fp , 100);    fclose($fp);   

a.php を実行した後、すぐに b.php を実行すると、出力が表示されます:
abc
a.php が実行されるのを待って、b.php を実行すると、出力が表示されます:
abc
123
明らかに、 a. php がファイルを書き込むとき、データが大きすぎて時間がかかります。このとき、b.php は不完全なデータを読み取ります

b.php を次のように変更します。

$file = "temp.txt";    $fp = fopen($file , 'r');    if(flock($fp , LOCK_EX)){        echo fread($fp , 100);        flock($fp , LOCK_UN);    } else{        echo "Lock file failed...\n";    }    fclose($fp);   

a.php を実行した後、 b.php は、a.php が完了するまで (つまり、10 秒後) 表示されるまで待機することがわかります:
abc
123
読み取りデータは完了しましたが、時間が長すぎます。 、書き込みロックが解除されるまで待たなければなりません。

b.php を次のように変更します:

$file = "temp.txt";    $fp = fopen($file , 'r');    if(flock($fp , LOCK_SH | LOCK_NB)){        echo fread($fp , 100);        flock($fp , LOCK_UN);    } else{        echo "Lock file failed...\n";    }    fclose($fp);   

a.php を実行した後、すぐに b.php を実行すると、出力が表示されます:
ロック ファイルが失敗しました...
代わりにロック ファイルの失敗ステータスを返すことができることを証明します。上記と同じリクエストの場合は、しばらく待ちます。

結論:
ファイルをキャッシュするときは、関連するロックを選択することをお勧めします。そうしないと、読み取られたデータが不完全になったり、データが繰り返し書き込まれたりする可能性があります。
file_get_contents はデフォルトでどのようなロックを使用するのかわかりませんが、ロックしない場合でも得られる出力は同じであり、不完全なデータです。
ファイルのキャッシュを実行したいので、書き込みロックがあるかどうかを知る必要があるだけで、ある場合はデータベースをチェックするだけです。
テスト環境: Linux (Ubuntu 6)、PHP 5.1.2、Apache 2

リダイレクト:

ファイル ロックには、共有ロックと排他ロック、つまり読み取りロック (LOCK_SH) と書き込みロック ( LOCK_EX)
ファイル ロックは通常次のように使用されます:

$fp = fopen("filename", "a"); flock($fp, LOCK_SH) または die("lock error") $str = fread($fp, 1024); flock($fp, LOCK_UN);


これは、ファイルが更新される前に fwrite を待ってから fclose するのではなく、fwrite の直後に更新されることに注意してください。 fwrite の後、fclose の前にチェックするファイル

しかし、いつ lock_ex を使用し、いつ lock_sh を使用するのでしょうか?

読み取り時:
ダーティなデータを表示したくない場合は、lock_sh 共有ロックを使用するのが最善です。次の 3 つの状況が考えられます:
1. 読み取り時に共有ロックが追加されていない場合、他のプログラムが書き込みを行おうとすると (書き込みがロックされているかどうかに関係なく)、書き込みはすぐに成功します。ちょうど半分を読み取って別のプログラムで書き込んだ場合、読み取った後半は前半と一致しない可能性があります(前半は修正前、後半は修正後)
2.読み取り時 共有ロックを掛けた後(読み取り専用なので排他ロックをする必要はありません)、この時点で他のプログラムは書き込みを開始しますので、書き込みプログラムはロックを使用しません。ファイルを直接変更すると、以前と同じ問題が発生します
3. 最も理想的な状況は、読み取り時にロック (lock_sh) し、書き込み時にロック (lock_ex) することです。このようにして、書き込みプログラムは読み取りを待機します。

書き込み時:
複数の書き込みプログラムがロックせずにファイルに対して同時に動作する場合、最終データの一部はプログラム a によって書き込まれ、一部はプログラム a によって書き込まれる可能性があります。プログラム b
書き込み時にロックされている場合、他のプログラムがそれを読み取りに来た場合、何を読み取りますか?
1. リーダーが共有ロックを適用しない場合、ダーティ データを読み取ります。たとえば、プログラムを書く場合、a、b、c の 3 つの部分を書く必要があります。a を書いた後、このときに読み込むのは b です。次に、ab を書きます。このとき、読み取るのは abc です。
2. 読み取りプログラムが以前に共有ロックを申請していた場合、読み取りプログラムは書き込みプログラムが abc の書き込みを完了するのを待ってから読み取ります。

よく書かれたブログ投稿もあります:

http://hxsdit.com/1110

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。