ホームページ バックエンド開発 PHPチュートリアル PHP_PHP チュートリアルで複数のユーザーが読み書きするときに空のファイルが発生する問題の解決策

PHP_PHP チュートリアルで複数のユーザーが読み書きするときに空のファイルが発生する問題の解決策

Jul 13, 2016 am 10:47 AM
php 使用 書く 方法 マルチユーザー 私たち 書類 時間 解決する 読み書き 移行 質問

其实解决多调用同时写一个文件时我们会使用flock来解决些问题,这样同一时间只有一个用户可以写文件,同时其它用户进行等待队列了,下面我来介绍一下flock解决多用户读写文件冲空问题


所以一般的方案会是:

 代码如下 复制代码

$fp = fopen("/tmp/lock.txt", "w+");
if (flock($fp, LOCK_EX)) {
    fwrite($fp, "Write something heren");
    flock($fp, LOCK_UN);
} else {
    echo "Couldn't lock the file !";
}
fclose($fp);

但在PHP中,flock似乎工作的不是那么好!在多并发情况下,似乎是经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉。好像在很多linux/unix系统中,都会有这样的情况发生。
所以使用flock之前,一定要慎重考虑。
那么就没有解决方案了吗?其实也不是这样的。如果flock()我们使用得当,完全可能解决死锁的问题。当然如果不考虑使用flock()函数,也同样会有很好的解决方案来解决我们的问题。
经过我个人的搜集和总结,大致归纳了解决方案有如下几种。
方案一:对文件进行加锁时,设置一个超时时间.
大致实现如下:

 代码如下 复制代码

if($fp = fopen($fileName, 'a')) {
 $startTime = microtime();
 do {
         $canWrite = flock($fp, LOCK_EX);
  if(!$canWrite) usleep(round(rand(0, 100)*1000));
 } while ((!$canWrite) && ((microtime()-$startTime) < 1000));
 if ($canWrite) {
   fwrite($fp, $dataToSave);
 }
 fclose($fp);
}

タイムアウトは1msに設定されており、この時間内にロックが取得できなかった場合は、当然ながらファイルの操作権が得られるまで繰り返しロックが取得されます。タイムアウト制限に達した場合は、ただちに終了してロックを放棄し、他のプロセスが動作できるようにする必要があります。
解決策 2: flock 関数を使用せず、一時ファイルを使用して読み取りと書き込みの競合の問題を解決します。
一般原則は次のとおりです:
1.更新する必要があるファイルを一時ファイル ディレクトリに置き、ファイルの最終変更時刻を変数に保存し、この一時ファイルに繰り返しにくいランダムなファイル名を付けます。
2.この一時ファイルを更新した後、元のファイルの最終更新時刻が以前に保存した時刻と一致しているかどうかを確認します。
3.最終変更時刻が同じ場合、変更された一時ファイルの名前が元のファイルに変更されます。ファイルのステータスが同期して更新されるようにするには、ファイルのステータスをクリアする必要があります。
4.ただし、最終変更時刻が以前に保存された時刻と一致する場合は、この期間中に元のファイルが変更されたことを意味し、この時点で一時ファイルを削除する必要があり、他のプロセスが削除されていることを示す false が返されます。現時点ではファイルを操作しています。
おおよその実装コードは次のとおりです:

コードは次のとおりです コードをコピー

$dir_fileopen = "tmp";

関数randomid() {
戻り time().substr(md5(microtime()), 0, rand(5, 12));
}
関数 cfopen($filename, $mode) {
グローバル $dir_fileopen;
clearstatcache();
やります{
$id = md5(randomid(rand(), TRUE));
$tempfilename = $dir_fileopen."/".$id.md5($filename);
while(file_exists($tempfilename));
If (file_exists($filename)) {
$newfile = false;
copy($filename, $tempfilename);
}その他{
$newfile = true;
}
$fp = fopen($tempfilename, $mode);
$fp を返しますか? array($fp, $filename, $id, @filemtime($filename)) : false;
}
関数 cfwrite($fp,$string) { return fwrite($fp[0], $string) }
function cfclose($fp, $debug = "off") {
グローバル $dir_fileopen;
$success = fclose($fp[0]);
clearstatcache();
$tempfilename = $dir_fileopen."/".$fp[2].md5($fp[1]);
if ((@filemtime($fp[1]) == $fp[3]) || ($fp[4]==true && !file_exists($fp[1])) || $fp[ 5]==true) {
rename($tempfilename, $fp[1]);
}その他{
unlink($tempfilename);
//対象ファイルを操作している他のプロセスがあり、現在のプロセスが拒否されたことを示します
$success = false;
}
$success を返します;
}
$fp = cfopen('lock.txt','a+');
cfwrite($fp,"北京へようこそ.n");
fclose($fp,'on');


上記のコードで使用されている関数については、次のことを説明する必要があります:
1.rename(); ファイルまたはディレクトリの名前を変更するこの関数は、実際には Linux の mv に似ています。ファイルやディレクトリのパスや名前を更新すると便利です。
ただし、ウィンドウで上記のコードをテストすると、新しいファイル名がすでに存在する場合、現在のファイルがすでに存在するという通知が表示されます。ただし、Linux では正常に動作します。
2.clearstatcache(); ファイルのステータスをクリアします。PHP はパフォーマンスを向上させるためにすべてのファイル属性情報をキャッシュしますが、複数のプロセスがファイルを削除または更新している場合、PHP はキャッシュ内のファイル属性を更新する時間がない場合があります。 . 最終更新時刻へのアクセスが実際のデータではなくなる可能性があります。したがって、ここではこの関数を使用して保存されたキャッシュをクリアする必要があります。

オプション 3: 同時実行の可能性を減らすために、操作されたファイルをランダムに読み書きします。
このソリューションは、ユーザーのアクセス ログを記録するときによく使用されるようです。
以前は、ランダムなスペースを定義する必要がありました。スペースが大きいほど、同時実行の可能性は低くなります。ランダムな読み取りおよび書き込みスペースが [1 ~ 500] であるとすると、ログ ファイルの分布は log1 から log500 の範囲になります。ユーザーがアクセスするたびに、log1 ~ log500 までの任意のファイルにデータがランダムに書き込まれます。
同時に、2 つのプロセスがログを記録しています。プロセス A は更新された log32 ファイルである可能性がありますが、プロセス B はどうなるでしょうか。このときの更新は log399 になる可能性があります。プロセス B にも log32 を実行させたい場合、確率は基本的に 1/500 であり、ほぼゼロに等しいことを知っておく必要があります。
アクセスログを分析する必要がある場合、ここでは、最初にこれらのログをマージしてから分析するだけです。
このソリューションを使用してログを記録する利点の 1 つは、プロセス操作がキューに入れられる可能性が比較的小さく、プロセスが各操作を非常に迅速に完了できることです。

オプション 4: 操作するすべてのプロセスをキューに入れます。次に、ファイル操作を完了するための専用サービスを配置します。
キュー内の除外された各プロセスは最初の特定の操作に相当するため、ここに多数のファイル操作プロセスがある場合、初めてサービスはキューから特定の操作アイテムを取得するだけで済みます。列の最後尾に並んでください。列に並ぶ意思がある限り、列の長さは関係ありません。

前述のオプションには、それぞれ独自の利点があります。大きく分けて2つのカテゴリーに分かれます
1.オプション 1、2、4 などのキューに入れる必要がある (影響は遅い)
2.並ぶ必要はありません。 (ファストインパクト) オプション 3
キャッシュ システムを設計する場合、通常、オプション 3 は採用しません。案3の解析プログラムと書き込みプログラムは同期していないため、書き込みの際に解析の難易度は全く考慮されず、書き込みがよければ問題ありません。想像してみてください。キャッシュの更新時にランダムなファイルの読み書きも行うと、キャッシュの読み込み時に多くの処理が追加されそうです。ただし、オプション 1 と 2 はまったく異なりますが、書き込み時間はかかりますが (ロックの取得に失敗した場合は繰り返し取得されます)、ファイルの読み取りは非常に便利です。キャッシュを追加する目的は、データ読み取りのボトルネックを軽減し、それによってシステムのパフォーマンスを向上させることです。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/632899.html技術記事実際、ファイルを書き込むために複数の呼び出しが同時に行われる場合、flock を使用していくつかの問題を解決します。これにより、他のユーザーがキューで待機している間、同時に 1 人のユーザーだけがファイルを書き込むことができます。 ..
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles