并发下常见的加锁及锁的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中的cookie
Nov 26 PHP
php 魔术方法使用说明
Oct 20 PHP
DW中链接mysql数据库时,建立字符集中文出现乱码的解决方法
Mar 27 PHP
PHP中__get()和__set()的用法实例详解
Jun 04 PHP
codeigniter数据库操作函数汇总
Jun 12 PHP
CI框架中cookie的操作方法分析
Dec 12 PHP
PHP处理postfix邮件内容的方法
Jun 16 PHP
Zend Framework教程之MVC框架的Controller用法分析
Mar 07 PHP
PHP获取网站中各文章的第一张图片的代码示例
May 20 PHP
header与缓冲区之间的深层次分析
Jul 30 PHP
PHP基于面向对象实现的留言本功能实例
Apr 04 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
Oct 18 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
《APMServ 5.1.2》使用图解
2006/10/23 PHP
解析MySql与Java的时间类型
2013/06/22 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
PHP实现的方程求解示例分析
2016/11/11 PHP
PHP获取当前执行php文件名的代码
2017/03/02 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
PHP实现websocket通信的方法示例
2018/08/28 PHP
jQuery 开天辟地入门篇一
2009/12/09 Javascript
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
jquery 跨域访问问题解决方法(笔记)
2011/06/08 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
JavaScript闭包函数访问外部变量的方法
2014/08/27 Javascript
js输入框使用正则表达式校验输入内容的实例
2017/02/12 Javascript
JavaScript 通过Ajax 动态加载CheckBox复选框
2017/08/31 Javascript
React组件中的this的具体使用
2018/02/28 Javascript
通过 JS 判断页面是否有滚动条的实现方法
2018/04/05 Javascript
vue2.0学习之axios的封装与vuex介绍
2018/05/28 Javascript
vue系列之requireJs中引入vue-router的方法
2018/07/18 Javascript
微信小程序全局变量改变监听的实现方法
2019/07/15 Javascript
vue实现简单加法计算器
2020/10/22 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[02:07]TI9显影之尘系列 - Vici Gaming
2019/08/20 DOTA
跟老齐学Python之重回函数
2014/10/10 Python
采用Psyco实现python执行速度提高到与编译语言一样的水平
2014/10/11 Python
Django中使用group_by的方法
2015/05/26 Python
Python类的用法实例浅析
2015/05/27 Python
Python计算一个文件里字数的方法
2015/06/15 Python
python 3调用百度OCR API实现剪贴板文字识别
2018/09/04 Python
Python Json数据文件操作原理解析
2020/05/09 Python
利用简洁的图片预加载组件提升html5移动页面的用户体验
2016/03/11 HTML / CSS
新郎父亲婚宴答谢词
2014/01/11 职场文书
简易版租房协议书范本
2014/10/13 职场文书
童年读书笔记
2015/06/26 职场文书
工作服管理制度范本
2015/08/06 职场文书
2019中秋节祝福语大全,提前收藏啦
2019/09/10 职场文书
拙作再改《我的收音机情缘》
2022/04/05 无线电