并发下常见的加锁及锁的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+Html+缓存
Nov 25 PHP
Windows7下PHP开发环境安装配置图文方法
May 20 PHP
php foreach 参数强制类型转换的问题
Dec 10 PHP
解析PHP SPL标准库的用法(遍历目录,查找固定条件的文件)
Jun 18 PHP
小谈php正则提取图片地址
Mar 27 PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
Jul 22 PHP
网站防止被刷票的一些思路与方法
Jan 08 PHP
比较完整的微信开发php代码
Aug 02 PHP
Zend Framework入门教程之Zend_Mail用法示例
Dec 08 PHP
PHP+ajax实现获取新闻数据简单示例
May 08 PHP
php过滤htmlspecialchars() 函数实现把预定义的字符转换为 HTML 实体用法分析
Jun 25 PHP
Laravel框架控制器的request与response用法示例
Sep 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&amp;&amp;mysql)二
2006/10/09 PHP
创建配置文件 用PHP写出自己的BLOG系统 2
2010/04/12 PHP
PHP实现WebService的简单示例和实现步骤
2015/03/27 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
PHP消息队列用法实例分析
2016/02/12 PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
2019/11/04 PHP
YII2框架使用控制台命令的方法分析
2020/03/18 PHP
细品javascript 寻址,闭包,对象模型和相关问题
2009/04/27 Javascript
ASP.NET jQuery 实例12 通过使用jQuery validation插件简单实现用户注册页面验证功能
2012/02/03 Javascript
详解Vue源码学习之双向绑定
2019/04/10 Javascript
详解一个小实例理解js原型和继承
2019/04/24 Javascript
Vue程序调试的方法
2019/06/17 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
JavaScript中clientWidth,offsetWidth,scrollWidth的区别
2021/01/25 Javascript
[01:08]DOTA2次级职业联赛 - Wings 战队宣传片
2014/12/01 DOTA
[59:59]EG vs IG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
使用PyCharm创建Django项目及基本配置详解
2018/10/24 Python
使用Python的SymPy库解决数学运算问题的方法
2019/03/27 Python
python3.5安装python3-tk详解
2019/04/26 Python
基于pytorch 预训练的词向量用法详解
2020/01/06 Python
python实现将字符串中的数字提取出来然后求和
2020/04/02 Python
使用Tensorflow-GPU禁用GPU设置(CPU与GPU速度对比)
2020/06/30 Python
python的链表基础知识点
2020/09/13 Python
Python创建自己的加密货币的示例
2021/03/01 Python
浅析HTML5页面元素及属性
2021/01/20 HTML / CSS
JSF面试题:Jsf中导航的标签是什么
2013/04/20 面试题
文明学生事迹材料
2014/01/29 职场文书
绿色学校实施方案
2014/03/31 职场文书
优秀应届毕业生自荐书
2014/06/29 职场文书
2015年禁毒宣传活动总结
2015/03/25 职场文书
单位收入证明范本
2015/06/18 职场文书
医院感染管理制度
2015/08/05 职场文书
大学生党课心得体会
2016/01/07 职场文书
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python
浅谈sql_@SelectProvider及使用注意说明
2021/08/04 Java/Android