并发下常见的加锁及锁的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 Document 代码注释规范
Apr 13 PHP
php SQL Injection with MySQL
Feb 27 PHP
基于php和mysql的简单的dao类实现crud操作功能
Jan 27 PHP
PHP中file_exists()判断中文文件名无效的解决方法
Nov 12 PHP
PHP中strtr字符串替换用法详解
Nov 26 PHP
PHP输出两个数字中间有多少个回文数的方法
Mar 23 PHP
php实现随机显示图片方法汇总
May 21 PHP
关于php 高并发解决的一点思路
Apr 16 PHP
详解PHP队列的实现
Mar 14 PHP
使用composer 安装 laravel框架的方法图文详解
Aug 02 PHP
tp5框架基于ajax实现异步删除图片的方法示例
Feb 10 PHP
PHP使用openssl扩展实现加解密方法示例
Feb 20 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
dedecms中常见问题修改方法总结
2007/03/21 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
一款JavaScript压缩工具:X2JSCompactor
2007/06/13 Javascript
javascript 广告后加载,加载完页面再加载广告
2010/11/25 Javascript
基于jquery的bankInput银行卡账号格式化
2012/08/22 Javascript
JavaScript中的console.profile()函数详细介绍
2014/12/29 Javascript
JavaScript判断IE版本型号
2015/07/27 Javascript
使用jquery.qrcode.min.js实现中文转化二维码
2016/03/11 Javascript
JS中判断字符串中出现次数最多的字符及出现的次数的简单实例
2016/06/03 Javascript
妙用Bootstrap的 popover插件实现校验表单提示功能
2016/08/29 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
基于JavaScript实现弹幕特效
2020/08/27 Javascript
bootstrap select下拉搜索插件使用方法详解
2017/11/23 Javascript
详解JavaScript 中 if / if...else...替换方式
2018/07/15 Javascript
node中的cookie的具体使用
2018/09/13 Javascript
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
微信小程序如何获取用户收货地址
2018/11/27 Javascript
zepto.js 实时监听输入框的方法
2018/12/04 Javascript
Element-ui DatePicker显示周数的方法示例
2019/07/19 Javascript
对Layer UI 模块化的用法详解
2019/09/26 Javascript
JavaScript实现更换背景图片
2019/10/18 Javascript
JS中的变量作用域(console版)
2020/07/18 Javascript
vue抽出组件并传值实例
2020/07/31 Javascript
python将html转成PDF的实现代码(包含中文)
2013/03/04 Python
python批量复制图片到另一个文件夹
2018/09/17 Python
Python3模拟登录操作实例分析
2019/03/12 Python
使用keras时input_shape的维度表示问题说明
2020/06/29 Python
基于CSS3实现的漂亮Menu菜单效果代码
2015/09/10 HTML / CSS
体育教师工作总结的自我评价
2013/10/10 职场文书
党课学习思想汇报
2014/01/02 职场文书
四风问题对照检查材料整改措施
2014/09/27 职场文书
工地材料员岗位职责
2015/04/11 职场文书
教师工作证明范本
2015/06/12 职场文书
新学期新寄语,献给新生们!
2019/11/15 职场文书
vue @click.native 绑定原生点击事件
2022/04/22 Vue.js