PHPプロセスロック問題の分析と研究_PHPチュートリアル
- WBOYオリジナル
- 2016-07-21 15:42:581233ブラウズ
1. 読み取りロックと書き込みロックを区別します。
書き込みロックが毎回使用される場合、ファイルを読み取るために複数のプロセスがキューに入る必要があり、これは明らかに効率的ではありません。
2. ブロッキング モードと非ブロッキング モードを区別します。
一般的に、1 つのプロセスがファイルを書き込んでいる場合、他のプロセスはブロックされる必要があります。ただし、多くの場合、最初に別の処理を行ってから、他の誰かがファイルを書き込んでいるかどうかを判断できます。「いいえ」の場合は、データを追加します。より効率的です。
3. Linux でのファイルのロックのバグ、特に gfs ファイル システムのバグを修正しました。
コードは次のとおりです:
コードをコピーします コードは次のとおりです:
class File_Lock
{
private $name;
private $mode; function __construct($filename, $mode = 'a+b')
{
global $php_errormsg;
$this->name = $filename;
if ( $path == '.' || !is_dir($path)) {
$this->name = str_replace(array("/", "_", ") _"), $this->name);
if ($config_file_lock_path == null) {
$this->name = dirname(__FILE__) . "/lock/" . $this->name;
} else {
$this->name = $config_file_lock_path . "/" . $this->name
}
$this->handle = @fopen( $this->name, $mode);
if ($this->handle == false) {
新しい例外をスロー($php_errormsg)
}
}
public function close()
{
if ($ this->ハンドル != = null ) {
@fclose($this->ハンドル);
$this->ハンドル = null
}
}
パブリック関数 __destruct()
{
$this-> ;close();
}
パブリック関数 lock($lockType, $nonBlockingLock = false)
{
if ($nonBlockingLock) {
return flock($this->handle, $lockType | LOCK_NB);
return flock($this->handle, $lockType);
}
}
public function readLock()
{
return $this->lock(LOCK_SH)
}
public function writeLock($wait = 0.1) )
{
$startTime = microtime(true);
$canWrite = false;
$canWrite = flock($this->handle, LOCK_EX) {
usleep(rand( 10, 1000));
}
} while ((!$canWrite) && ((microtime(true) - $startTime) < $wait));
}
/**
* マルチスレッドシステムで番号を記録したくない場合は、
* ロックを開いて、+ MOD を使用してください。ファイルを fopen してもデータは
* 破壊されません。
*
* この関数は、delt 値をインクリメントし、ファイルに保存します。
*
* @param int $delt
* @return int
*/
パブリック関数インクリメント($delt = 1)
{
$n = $this->get();
$this->set($n);
public関数 get()
{
fseek($this->handle, 0);
return (int)fgets($this->handle)
}
public function set($value)
{
ftruncate($) this->ハンドル, 0 );
return fwrite($this->handle, (string)$value);
パブリック関数unlock()
{
if ($this->handle !== null ){Return Flock($&gt; lock_un);は次のとおりです:
& lt;? php
/**
* テスト書き込みロック
* スレッド 1 を開く
*/
require("file_lock.php");
$lock = new File_Lock(dirname(dirname(__FILE__)) . "/FileLock.ロック");
/**単一スレッドのロック速度は 1 秒あたり 30,000 回です。 * */
/**2 つのスレッドで 20,000 データを書き込み、約 7 秒かかります*/
/**1 スレッドで 10,000 データを書き込むのにかかる時間は約 3.9 秒です。実際には 2 つのファイルが同時に書き込まれるため、より高速になります。*/
/**ロックしない場合、プロセスの書き込みには約 2.8 秒かかります。ロックには代償が伴います。*/
/**ロックがないと、2 つのプロセスの分散はあまり均等ではなくなり、ほとんどのプロセスが競合します。*/
$lock->writeLock();
$lock->increment();
while ($lock->get() < 2) {
usleep(1000) ;
}
sleep(1);
echo "n の実行を開始";
$t1 = microtime(true);
{
$lock- >writeLock();
$lock->unlock();
$t2 = $t1;>
単純なスレッド同期を実現し、2 つのプロセスが特定のコードを同時に実行できるようにするインクリメント関数を追加しました。もちろん、これには一定のエラーがあります
ここでのエラーは 0.001 秒です。
前の memcache メッセージ キューでこのクラスを使用するだけで、スレッドセーフなメッセージ キューを実装できます。
http://www.bkjia.com/PHPjc/320820.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/320820.html技術記事 1. 読み取りロックと書き込みロックを区別します。 毎回書き込みロックを使用すると、ファイルを読み取るために複数のプロセスがキューに入る必要があり、明らかに効率的ではありません。 2. ブロックと非ブロックを区別する...
声明:この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。