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;
$path = dirname($this->name);
if ($path == '.' || ! is_dir($path)) {
global $config_file_lock_path;
$this->name = str_replace(array("/", "\"), array("_", "_"), $this ->name);
if ($config_file_lock_path == null) {
$this->name = dirname(__FILE__) . else {
$ this->name = $config_file_lock_path . $this->name;
$this->mode = $mode; $this->handle = @fopen($this->name, $mode);
if ($this->handle == false) {
throw new Exception($php_errormsg); >}
}
public function close()
{
if ($this->handle !== null ) {
@fclose($this->handle); 🎜>$this->handle = null;
}
}
パブリック関数 __destruct()
{
$this->close()
public function 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) ;
}
パブリック関数 writeLock($wait = 0.1)
{
$startTime = microtime(true);
do {
$canWrite; = flock($this- >handle, LOCK_EX);
if(!$canWrite) {
usleep(rand(10, 1000)); while ((!$canWrite) ) && ((microtime( true) - $startTime) < $wait));
}
/**
* マルチスレッドシステムで番号を記録したくない場合は、
* ロックを開いて、MOD を使用してください。ファイルを fopen しても
* データは破壊されません。
*
* この関数はデルト値をインクリメントし、ファイルに保存します。
*
* @param int $delt
* @return int
*/
パブリック関数 increment($delt = 1)
{
$n = $this->get();
$this->set($n);
return $n; 🎜>パブリック関数 get( )
{
fseek($this->handle, 0)
return (int)fgets($this->handle);
public function set($value )
{
ftruncate($this->handle, 0);
return fwrite($this->handle, (string)$value);
パブリック関数unlock ()
{
if ($this->handle !== null ) {
return flock($this->handle,
} else; {
return true ;
}
}
}
?>
テストコード:
code
コードは次のとおりです。
/**
* 書き込みロックテストを実行します
* スレッド 1 を開きます
*/
require("file_lock.php"); 🎜>$lock = new File_Lock(dirname (dirname(__FILE__)) . "/FileLock.lock");
/**単一スレッドのロック速度は 1 秒あたり 30,000 回です。 **/
/**2 つのスレッドで 20,000 データを書き込み、約 7 秒かかります*/
$lock->writeLock(); (); $lock->unlock(); while ($lock->get() < 2) { usleep(1000)>} 1);
エコー "n の実行を開始";$t1 = microtime(true);
for ($i = 0; $i <10000; $i ); >$lock->writeLock() ;
$lock->unlock();
}
$t2 (true) - $t1;
echo $t2 ;
?>
単純なスレッド同期を実現し、2 つのプロセスが同時に実行できるようにします。もちろん、これには一定の誤差があります
ここでの誤差は 0.001 秒です。
前の memcache メッセージ キューでこのクラスを使用するだけで、スレッドセーフなメッセージ キューを実装できます。