并发下常见的加锁及锁的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 相关文章推荐
MySql中正则表达式的使用方法描述
Jul 30 PHP
php include,include_once,require,require_once
Sep 05 PHP
PHP计划任务、定时执行任务的实现代码
Apr 23 PHP
php中设置多级目录session的问题
Aug 08 PHP
ThinkPHP实现一键清除缓存方法
Jun 26 PHP
兼容ie6浏览器的php下载文件代码分享
Jul 14 PHP
PHP使用Mysql事务实例解析
Sep 08 PHP
php去除头尾空格的2种方法
Mar 16 PHP
php实现的单一入口应用程序实例分析
Sep 23 PHP
浅析Yii2 GridView实现下拉搜索教程
Apr 22 PHP
PHP开发中csrf攻击的简单演示和防范
May 07 PHP
ThinkPHP实现的rsa非对称加密类示例
May 29 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
一个取得文件扩展名的函数
2006/10/09 PHP
PHP中获取变量的变量名的一段代码的bug分析
2011/07/07 PHP
php数组中删除元素的实现代码
2012/06/22 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
用一段js程序来实现动画功能
2007/03/06 Javascript
取消选中单选框radio的三种方式示例介绍
2013/12/23 Javascript
js获取当前页面路径示例讲解
2014/01/08 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
jQuery中detach()方法用法实例
2014/12/25 Javascript
jquery仿百度百科底部浮动导航特效
2015/08/08 Javascript
jquery彩色投票进度条简单实例演示
2020/07/23 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
设置jQueryUI DatePicker默认语言为中文
2016/06/04 Javascript
小程序开发实战:实现九宫格界面的导航的代码实现
2017/01/19 Javascript
Angular ui.bootstrap.pagination分页
2017/01/20 Javascript
Angular4.0中引入laydate.js日期插件的方法教程
2017/12/25 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
2018/09/21 Javascript
js实现图片区域可点击大小随意改变(适用移动端)代码实例
2019/09/11 Javascript
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
vue.js 实现a标签href里添加参数
2019/11/12 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
深入了解JS之作用域和闭包
2020/06/16 Javascript
python在多玩图片上下载妹子图的实现代码
2013/08/13 Python
给Python的Django框架下搭建的BLOG添加RSS功能的教程
2015/04/08 Python
Python只用40行代码编写的计算器实例
2017/05/10 Python
django上传图片并生成缩略图方法示例
2017/12/11 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
Python Learning 列表的更多操作及示例代码
2018/08/22 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
Python3 requests模块如何模仿浏览器及代理
2020/06/15 Python
高中生自我鉴定范文
2013/10/30 职场文书
酒吧员工的岗位职责
2013/11/26 职场文书
全运会口号
2014/06/20 职场文书
《鲁班学艺》读后感3篇
2019/11/27 职场文书