并发下常见的加锁及锁的PHP具体实现代码


Posted in PHP onOctober 12, 2010

在最近的项目中有这样的场景
1.生成文件的时候,由于多用户都有权限进行生成,防止并发下,导致生成的结果出现错误,需要对生成的过程进行加锁,只容许一个用户在一个时间内进行操作,这个时候就需要用到锁了,将这个操作过程锁起来.
2.在用了cache的时候,cache失效可能导致瞬间的多数并发请求穿透到数据库此时也可以得需要用锁在同一并发的过程中将这个操作锁定.

针对以上的2种情况,现在的解决方法是对处理过程进行锁机制,通过PHP实现如下
用到了Eaccelerator的内存锁 和 文件锁,原理如下
判断系统中是否安了EAccelerator 如果有则使用内存锁,如果不存在,则进行文件锁
根据带入的key的不同可以实现多个锁直接的并行处理,类似Innodb的行级锁

使用如下:
$lock = new CacheLock('key_name');
$lock->lock();
//logic here
$lock->unlock();
//使用过程中需要注意下文件锁所在路径需要有写权限.
具体类如下:

<?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) 
{ 
//配置目录权限可写 
$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); 
} 
} 
}

本类在孙立同学的类的基础上做了小点改进的了.具体可以看 http://code.google.com/p/phplock 感谢孙同学的分享精神!
PHP 相关文章推荐
PHP操作xml代码
Jun 17 PHP
php url地址栏传中文乱码解决方法集合
Jun 25 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
Nov 10 PHP
PHP 查找字符串常用函数介绍
Jun 07 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
Jun 06 PHP
php 模拟post_验证页面的返回状态(实例讲解)
Oct 28 PHP
destoon首页调用求购供应信息的地区名称的方法
Aug 21 PHP
php获取一个变量的名字的方法
Sep 05 PHP
Ajax提交表单时验证码自动验证 php后端验证码检测
Jul 20 PHP
php简单实现文件或图片强制下载的方法
Dec 06 PHP
PHP 观察者模式深入理解与应用分析
Sep 25 PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
Feb 15 PHP
PHP开发的一些注意点总结
Oct 12 #PHP
php更改目录及子目录下所有的文件后缀的代码
Sep 24 #PHP
比较全面的PHP数组的使用方法小结
Sep 23 #PHP
PHP之COOKIE支持详解
Sep 20 #PHP
PHPCMS的使用小结
Sep 20 #PHP
PHP中的MYSQL常用函数(php下操作数据库必备)
Sep 12 #PHP
zen cart新进商品的随机排序修改方法
Sep 10 #PHP
You might like
强烈推荐:php.ini中文版(2)
2006/10/09 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
php数组转成json格式的方法
2015/03/09 PHP
PHP文件操作之获取目录下文件与计算相对路径的方法
2016/01/08 PHP
浅谈PHP各环境下的伪静态配置
2019/03/13 PHP
Laravel中10个有用的用法小结
2019/05/06 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
PHP dirname(__FILE__)原理及用法解析
2020/10/28 PHP
用javascript替换URL中的参数值示例代码
2014/01/27 Javascript
jQuery中first()方法用法实例
2015/01/06 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
2015/08/17 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
将angular-ui的分页组件封装成指令的方法详解
2017/05/10 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
JS判断字符串是否为整数的方法--简单的正则判断
2018/07/23 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
vue+elementUI 实现内容区域高度自适应的示例
2020/09/26 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
JavaScript仿京东轮播图效果
2021/02/25 Javascript
[04:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster 选手采访
2021/03/11 DOTA
35个Python编程小技巧
2014/04/01 Python
Python+matplotlib实现填充螺旋实例
2018/01/15 Python
python执行系统命令后获取返回值的几种方式集合
2018/05/12 Python
python reverse反转部分数组的实例
2018/12/13 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
python 弹窗提示警告框MessageBox的实例
2019/06/18 Python
Python+OpenCv制作证件图片生成器的操作方法
2019/08/21 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
幼儿园大班开学教师寄语
2014/04/03 职场文书
干部对照检查材料范文
2014/08/26 职场文书
励志广播稿300字(5篇)
2014/09/15 职场文书
股东协议书范本2016
2016/03/21 职场文书
技术入股协议书
2016/03/22 职场文书
OpenCV 图像梯度的实现方法
2021/07/25 Python