ホームページ >バックエンド開発 >PHPの問題 >PHP は、複数のプロセスが同時にファイルを書き込む問題をどのように解決しますか?

PHP は、複数のプロセスが同時にファイルを書き込む問題をどのように解決しますか?

coldplay.xixi
coldplay.xixiオリジナル
2020-06-30 15:58:393567ブラウズ

php メソッドは、複数のプロセスが同時にファイルを書き込む問題を解決します。まず、更新する必要があるファイルをコピーし、ファイル名を変更します。次に、最終更新時刻が以前の更新時刻と一致しているかどうかを確認します。時間を節約し、最後に一時ファイルを変更し、元のファイルに名前を変更します。

PHP は、複数のプロセスが同時にファイルを書き込む問題をどのように解決しますか?


#php メソッドを使用して、複数のプロセスがファイルを書き込む問題を解決します。同時に:

まず第一に、PHP はプロセスをサポートしていますが、マルチスレッドはサポートしていません (これを最初に明確にしてください)。ファイル操作の場合、実際にはファイルをロックするだけで済みます。問題を解決します。他の操作は必要ありません。PHP flock が自動的に解決します。

flock を使用して、書き込み前にファイルをロックし、書き込み後にロックを解除します。これにより、競合を避けるために、複数のスレッドが同時にファイルの読み取りと書き込みを行うことができます。それはおそらく次のプロセスです

/*
*flock(file,lock,block)
*file 必需,规定要锁定或释放的已打开的文件
*lock 必需。规定要使用哪种锁定类型。
*block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。
*lock
*LOCK_SH 要取得共享锁定(读取的程序)
*LOCK_EX 要取得独占锁定(写入的程序)
*LOCK_UN 要释放锁定(无论共享或独占)
*LOCK_NB 如果不希望 flock() 在锁定时堵塞
/*
if (flock($file,LOCK_EX))
{
fwrite($file,'write more words');
flock($file,LOCK_UN);
}
else
{
//处理错误逻辑
}
fclose($file);
)

関連する学習の推奨事項:

PHP プログラミングの入門から熟練度まで

解決策: flock 関数を使用しないでください, 一時ファイルを使用して、読み取りと書き込みの競合を解決します。

一般原則は次のとおりです:

(1) 更新する必要があるファイルのコピーを一時ファイル ディレクトリに置き、ファイルの最終変更時刻を保存します。変数に代入し、これを設定します。一時ファイルには、重複する可能性の低いランダムなファイル名が付けられます。

(2) この一時ファイルを更新した後、元のファイルの最終更新時刻が以前に保存した時刻と一致しているかどうかを確認します。

(3) 最終変更時刻が同じ場合は、変更した一時ファイルを元のファイルに変更します ファイルのステータスを同期して更新するためには、ファイルのステータスをクリアする必要があります。

(4) ただし、最終変更時刻が前回保存した時刻と一致する場合は、その期間内に元のファイルが変更されたことになりますので、この時点で一時ファイルを削除する必要があります。その後 false を返し、ファイルが現在他のプロセスによって操作されていることを示します。

実装コードは次のとおりです:

コードは次のとおりです:

$dir_fileopen='tmp';
function randomid(){
    return time().substr(md5(microtime()),0,rand(5,12));
}
function cfopen($filename,$mode){
    global $dir_fileopen;
    clearstatcache();
    do{
  $id=md5(randomid(rand(),TRUE));
        $tempfilename=$dir_fileopen.'/'.$id.md5($filename);
    } while(file_exists($tempfilename));
    if(file_exists($filename)){
        $newfile=false;
        copy($filename,$tempfilename);
    }else{
        $newfile=true;
    }
    $fp=fopen($tempfilename,$mode);
    return $fp?array($fp,$filename,$id,@filemtime($filename)):false;
}
function cfwrite($fp,$string){
 return fwrite($fp[0],$string);
}
function cfclose($fp,$debug='off'){
    global $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]);
    }else{
        unlink($tempfilename);
  //说明有其它进程 在操作目标文件,当前进程被拒绝
        $success=false;
    }
    return $success;
}
$fp=cfopen('lock.txt','a+');
cfwrite($fp,"welcome to beijing.\n");
fclose($fp,'on');

上記のコードで使用されている関数については、説明が必要です:

(1)

rename();ファイルまたはディレクトリの名前を変更します。この関数は実際には Linux の mv に似ています。ファイルやディレクトリのパスや名前を更新すると便利です。ただし、ウィンドウで上記のコードをテストすると、新しいファイル名がすでに存在する場合、現在のファイルがすでに存在するという通知が表示されます。ただし、Linux では正常に動作します。

(2)

clearstatcache();ファイルのステータスをクリアします。php はパフォーマンスを向上させるためにすべてのファイル属性情報をキャッシュしますが、場合によっては、複数のプロセスがファイルを削除したり、更新操作を実行すると、PHP にはキャッシュ内のファイル属性を更新する時間がなくなり、アクセスされた最終更新時刻が実際のデータではないという事実が簡単に発生する可能性があります。したがって、ここではこの関数を使用して保存されたキャッシュをクリアする必要があります。

以上がPHP は、複数のプロセスが同時にファイルを書き込む問題をどのように解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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