并发下常见的加锁及锁的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 相关文章推荐
用DBSQL类加快开发MySQL数据库程序的速度
Oct 09 PHP
轻松修复Discuz!数据库
May 03 PHP
PHP伪静态写法附代码
Jun 20 PHP
php 空格,换行,跳格使用说明
Dec 18 PHP
PHP 多维数组的排序问题 根据二维数组中某个项排序
Nov 09 PHP
php中如何使对象可以像数组一样进行foreach循环
Aug 09 PHP
从PHP $_SERVER相关参数判断是否支持Rewrite模块
Sep 26 PHP
用PHP代替JS玩转DOM的思路及示例代码
Jun 15 PHP
PHP实现定时执行任务的方法
Oct 05 PHP
php+ajax实现文章自动保存的方法
Dec 30 PHP
php版微信公众平台回复中文出现乱码问题的解决方法
Sep 22 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
Nov 21 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程序
2006/10/09 PHP
PHP中动态HTML的输出技术
2006/10/09 PHP
php动态变量定义及使用
2015/06/10 PHP
PHP实现获取某个月份周次信息的方法
2015/08/11 PHP
PHP简单处理表单输入的特殊字符的方法
2016/02/03 PHP
微信公众平台开发教程④ ThinkPHP框架下微信支付功能图文详解
2019/04/10 PHP
JQUERY设置IFRAME的SRC值的代码
2010/11/30 Javascript
Jquery写一个鼠标拖动效果实现原理与代码
2012/12/24 Javascript
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
javascript创建和存储cookie示例
2014/01/07 Javascript
使用jQuery判断Div是否在可视区域的方法 判断div是否可见
2016/02/17 Javascript
解析NodeJs的调试方法
2016/12/11 NodeJs
JS将unicode码转中文方法
2017/05/08 Javascript
浅析JavaScript中的平稳退化(graceful degradation)
2017/07/24 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
jQuery.extend 与 jQuery.fn.extend的用法及区别实例分析
2018/07/25 jQuery
angularjs手动识别字符串中的换行符方法
2018/10/02 Javascript
elementUI多选框反选的实现代码
2019/04/03 Javascript
如何使用JavaScript实现栈与队列
2019/06/24 Javascript
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[01:03:36]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第二场 1月26日
2021/03/11 DOTA
python使用xmlrpc实例讲解
2013/12/17 Python
Python多线程下载文件的方法
2015/07/10 Python
python 3利用Dlib 19.7实现摄像头人脸检测特征点标定
2018/02/26 Python
关于python字符串方法分类详解
2019/08/20 Python
python excel转换csv代码实例
2019/08/26 Python
巧用CSS3的calc()宽度计算做响应模式布局的方法
2018/03/22 HTML / CSS
大专毕业生自我鉴定
2013/11/21 职场文书
配件采购员岗位职责
2013/12/03 职场文书
给酒店员工的表扬信
2014/01/11 职场文书
教师专业自荐信
2014/05/31 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
践行党的群众路线心得体会
2014/11/05 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
社区挂职锻炼个人工作总结
2015/10/23 职场文书