并发下常见的加锁及锁的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实现验证码功能
Oct 09 PHP
PHP4和PHP5性能测试和对比 测试代码与环境
Aug 17 PHP
php面向对象全攻略 (十六) 对象的串行化
Sep 30 PHP
一个典型的PHP分页实例代码分享
Jul 28 PHP
php中计算中文字符串长度、截取中文字符串的函数代码
Aug 09 PHP
PHP中空字符串介绍0、null、empty和false之间的关系
Sep 25 PHP
浅析PHP原理之变量(Variables inside PHP)
Aug 09 PHP
Yii 快速,安全,专业的PHP框架
Sep 03 PHP
PHP获取远程图片并保存到本地的方法
May 12 PHP
ThinkPHP模型详解
Jul 27 PHP
ThinkPHP 3.2.2实现事务操作的方法
May 05 PHP
PHP实现通过CURL上传文件功能示例
May 30 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/11/26 PHP
Php output buffering缓存及程序缓存深入解析
2013/07/15 PHP
php 伪静态之IIS篇
2014/06/02 PHP
解密ThinkPHP3.1.2版本之模板继承
2014/06/19 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
2015/12/17 PHP
通过Unicode转义序列来加密,按你说的可以算是混淆吧
2007/05/06 Javascript
jquery 插件学习(三)
2012/08/06 Javascript
js 操作select和option常用代码整理
2012/12/13 Javascript
jquery 表格排序、实时搜索表格内容(附图)
2014/05/19 Javascript
javascript表单验证大全
2015/08/12 Javascript
JS实现很实用的对联广告代码(可自适应高度)
2015/09/18 Javascript
Position属性之relative用法
2015/12/14 Javascript
JavaScript组件开发完整示例
2015/12/15 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
jquery中的常见问题及快速解决方法小结
2016/06/14 Javascript
JavaScript DOM 对象深入了解
2016/07/20 Javascript
Vue.js实现实例搜索应用功能详细代码
2017/08/24 Javascript
Vue动态组件和异步组件原理详解
2019/05/06 Javascript
javascript中导出与导入实现模块化管理教程
2020/12/03 Javascript
vue 通过base64实现图片下载功能
2020/12/19 Vue.js
详解Python编程中基本的数学计算使用
2016/02/04 Python
python判断字符串编码的简单实现方法(使用chardet)
2016/07/01 Python
python基于ID3思想的决策树
2018/01/03 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
python在新的图片窗口显示图片(图像)的方法
2019/07/11 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
django model通过字典更新数据实例
2020/04/01 Python
Django中文件上传和文件访问微项目的方法
2020/04/27 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
2020/05/11 Python
欧舒丹澳洲版:L’OCCITANE
2017/07/17 全球购物
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
企业演讲稿范文
2013/12/28 职场文书
中学生自我鉴定
2014/02/04 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书
文明礼貌主题班会
2015/08/14 职场文书