PHP でのファイル ロックと mysql テーブル ロックの一般的な使用法は、同時に操作できるのは 1 人だけです。これにより、複数の人が同じファイルを同時に操作してデータの損失につながる状況を回避できます。 PHP ファイルロックの使用法については以下で説明します。
PHPにはファイルロック機能が付属しています:
bool flock ( int $handle , int $operation [, int &$wouldblock ] )
$handle は開いているファイル ポインターです。
$操作は
可能です
「LOCK_SH」は共有ロック、「LOCK_EX」は排他ロック、「LOCK_UN」はロックを解除します。
ここでは主に「LOCK_EX」と「LOCK_NB」について説明します。
flocka.php
コードをコピー | |
$file = 'temp.txt';
$fp = fopen($file,'a'); |
コードをコピー | |
$fp = fopen($file,'a'); for($i = 0;$i { fwrite($fp, "22222222n"); } fclose($fp); |
11111111
22222222
22222222
22222222
22222222
22222222
11111111
11111111
11111111
11111111
ファイル ロックが追加されていない場合、2 つのファイルが同時に txt ファイルに書き込まれることに注意してください。
2 つの php ファイルのコードを変更してみましょう。
flocka.php
コードをコピー | |||||||||||||
If(flock($fp,LOCK_EX)) { for($i = 0;$i { fwrite($fp, "11111111n"); 睡眠(1); } 群れ($fp,LOCK_UN); } fclose($fp) |
コードは次のとおりです | コードをコピー |
$file = 'temp.txt'; $fp = fopen($file,'a'); If(flock($fp,LOCK_EX)) { for($i = 0;$i { fwrite($fp, "22222222n"); } 群れ($fp,LOCK_UN); } fclose($fp) |
同様に、最初に flocka.php を実行し、その後すぐに flockb.php を実行します。
flocka.php の実行が終了する前に、flockb.php が待機状態になっていることがわかります。flocka.php の実行が終了した場合にのみ、flockb.php は実行を続けます。
出力結果:
11111111
11111111
11111111
11111111
11111111
22222222
22222222
22222222
22222222
22222222
また、flockを実行するとファイルのロックが自動的に解除されます。
別の方法もあります
次のコードは、このトランザクションの同時実行状態を単純にシミュレートします: process1.php
コードは次のとおりです | コードをコピー |
$num = 100; $filename = "プロセスデータ.txt"; $fp = fopen($filename, "a"); for ($i = 0; $i fwrite($fp, "process1: " . $i . "rn"); usleep(100000); } fclose($fp); ?> |
最初のトランザクションを最初に実行し、これらの 100 行を processdata.txt ファイルに書き込む必要があります。
プロセス2.php
コードは次のとおりです | コードをコピー |
$num = 100; |
2 番目のトランザクションは、processdata.txt ファイルに 100 行を書き込み続けます。
2 番目のトランザクションは、processdata.txt ファイルに 100 行を書き込み続けます。
同時に複数回実行すると、100行書き込まれましたが、トランザクション1とトランザクション2のデータがインターリーブされており、望む結果ではありません。現時点で必要なのは、トランザクションの完全な実行です。最初のトランザクションの実行後に 2 番目のトランザクションが確実に実行されるようにするメカニズムが必要です。 PHP では、flock 関数がこの使命を達成します。トランザクション 1 とトランザクション 2 のループの前に flock($fp, LOCK_EX); を追加すると、ニーズを満たし、2 つのトランザクションをシリアル化できます。
トランザクションが flock を完了すると、ここで追加したのは LOCK_EX (排他ロック) であるため、トランザクションが完了した後でのみ、リソースに対するすべての操作がブロックされます。現在時刻を出力することでこれを確認できます。
末尾への追加に関して、Unix システムの初期のバージョンには同時書き込みの問題があります。末尾に追加したい場合は、最初に位置をシークしてから書き込む必要があります。複数のプロセスが同時に動作する場合、同時実行性による上書き書き込みの問題が発生します。つまり、2 つのプロセスが同時に末尾オフセットを取得した後、次々に書き込み操作が実行され、後続の操作が上書きされてしまいます。以前の操作。この問題は、後に開くときに O_APPEND 操作を追加することで解決されました。これにより、検索操作と書き込み操作がアトミック操作に変わりました。
PHP の fopen 関数の実装では、a パラメーターを使用してファイルの末尾にコンテンツを追加する場合、open 関数呼び出しの oflag パラメーターは O_CREAT|O_APPEND になります。つまり、同時追加について心配する必要はありません。追加操作を使用する場合の書き込み。
Flock ファイル ロックは、PHP セッションのデフォルトのストレージ実装でも使用されます。セッションが開始されると、PS_READ_FUNC が呼び出され、O_CREAT | O_RDWR | O_BINARY でセッション データ ファイルが開かれます。他のプロセスがこのファイルにアクセスした場合 (つまり、同じユーザーが現在のファイルに対するリクエストを再度開始した場合)、ページがロード中であり、プロセスがブロックされていることが表示されます。書き込みロックを追加する開始点は、このセッションのセッション操作トランザクションが完全に実行できることを確認し、他のプロセスからの干渉を防ぎ、データの一貫性を確保することです。ページ上でセッション変更操作がない場合は、できるだけ早く session_write_close() を呼び出してロックを解放できます。
ファイルロックはファイルのロックです。この解釈に加えて、ファイルをロックとして使用することもできます。実際の作業では、単一のプロセスを確実に実行するために、プログラムの実行前にファイルが存在するかどうかを判断し、存在しない場合は空のファイルを作成し、存在する場合はプロセスの終了後に空のファイルを削除することがあります。 、実行されません。