您的位置:首页 > 编程语言 > PHP开发

PHP文件锁同步实例

2016-11-29 10:34 453 查看
该文件锁达到的效果是:

PHP语言中:多个请求,在同一时间段内,访问同一段代码,改代码只能同时处理一个请求,其它的请求排队等候,等一个请求处理完后,再依次处理剩余的请求。

类似于Java的synchronized线程同步。

实现的步骤如下(使用过程中需要注意下文件锁所在路径需要有写权限):

1、编辑一个进程锁类CacheLock.class.php

<?php
/**
* CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库
* 用于解决PHP在并发时候的锁控制,通过文件/eaccelerator进行进程间锁定
* 如果没有使用eaccelerator则进行进行文件锁处理,会做对应目录下产生对应粒度的锁
* 使用了eaccelerator则在内存中处理,性能相对较高
* 不同的锁之间并行执行,类似mysql innodb的行级锁
* 本类在sunli的phplock的基础上做了少许修改 http://code.google.com/p/phplock * @author yangxinqi
*
*/
class CacheLock {
//文件锁存放路径
private $path = null;
//文件句柄
private $fp = null;
//锁粒度,设置越大粒度越小
private $hashNum = 100;
//cache key
private $name;
//是否存在eaccelerator标志
private $eAccelerator = false;
/**
* 构造函数
* 传入锁的存放路径,及cache key的名称,这样可以进行并发
* @param string $path 锁的存放目录,以"/"结尾
* @param string $name cache key
*/
public function __construct($name, $path = 'lock\\') {
//判断是否存在eAccelerator,这里启用了eAccelerator之后可以进行内存锁提高效率
$this -> eAccelerator = function_exists("eaccelerator_lock");
if (!$this -> eAccelerator) {
$this -> path = $path.($this -> _mycrc32($name) % $this -> hashNum).
'.txt';
}
$this -> name = $name;
}
/**
* crc32
* crc32封装
* @param int $string
* @return int
*/
private function _mycrc32($string) {
$crc = abs(crc32($string));
if ($crc & 0x80000000) {
$crc ^= 0xffffffff;
$crc += 1;
}
return $crc;
}
/**
* 加锁
* Enter description here ...
*/
public function lock() {
//如果无法开启ea内存锁,则开启文件锁
if (!$this -> eAccelerator) {
//配置目录权限可写
//echo $this -> path;
//die();
$this -> fp = fopen($this -> path, 'w+');
if ($this -> fp === false) {
return false;
}
return flock($this -> fp, LOCK_EX);
} else {
return eaccelerator_lock($this -> name);
}
}
/**
* 解锁
* Enter description here ...
*/
public function unlock() {
if (!$this -> eAccelerator) {
if ($this -> fp !== false) {
flock($this -> fp, LOCK_UN);
clearstatcache();
}
//进行关闭
fclose($this -> fp);
} else {
return eaccelerator_unlock($this -> name);
}
}
}
2、在CacheLock.class.php文件的同级目录下新建一个lock的空文件夹

至此,已经配置完成。接下来就是测试使用。

3、分别建立讲个php文件index.php和index2.php。

index.php:

<?php
require 'CacheLock.class.php';
$lock = new CacheLock('key_name');
/*	这里是要同步的代码块	开始	*/
$lock->lock();
for($a=1;$a<5;$a++){
file_put_contents("test.txt", "***********第一个文件[" . $a . "].\n", FILE_APPEND);
sleep(2);
echo '正在写入第  ' . $a . '个文件。';
}
/*	这里是要同步的代码块	结束	*/
$lock->unlock();
?>
index2.php:

<?php
require 'CacheLock.class.php';
$lock = new CacheLock('key_name');
/*	这里是要同步的代码块	开始	*/
$lock->lock();
for($a=1;$a<5;$a++){
file_put_contents("test.txt", "第二个文件[" . $a . "].\n", FILE_APPEND);
sleep(2);
echo '正在写入第  ' . $a . '个文件。';
}
/*	这里是要同步的代码块	结束	*/
$lock->unlock();
?>

这两个文件代码几乎一模一样,只是输出文件(file_put_contents)的内容不一样,循环4次写入文件内容。

其中:$lock = new CacheLock('key_name');为关键,'key_name'就是要同步的标识,两个地方的'key_name'需要设置相同。

目录结构如下:



4、现在同时在浏览器中打开index.php和index2.php



执行完成以后可以看到目录下生成了一个text.txt文件



写入的顺序是第一个index.php中的代码执行完后才执行index2.php中的代码。达到了同步的效果。

Demo下载地址:http://download.csdn.net/detail/u014175572/9696452

参考前辈的文章:http://www.jb51.net/article/24962.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: