[转]并发下常见的加锁及锁的PHP具体实现
来源:互联网 发布:最小生成树算法 编辑:程序博客网 时间:2024/06/05 06:54
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; background-color: rgb(245, 245, 245);">在最近的项目中有这样的场景</span>
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 感谢孙同学的分享精神!
0 0
- [转]并发下常见的加锁及锁的PHP具体实现
- 并发下常见的加锁及锁的PHP具体实现
- 并发下常见的加锁及锁的PHP具体实现
- 并发下常见的加锁及锁的PHP具体实现
- 并发下常见的加锁及锁的PHP具体实现
- 并发下常见的加锁及锁的PHP具体实现
- PHP并发操作时的加锁功能
- PHP文件上传的具体思路及实现
- 用PHP文件上传的具体思路及实现
- php并发加锁
- PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
- PHP和Redis实现在高并发下的抢购及秒杀功能
- PHP在并发下的锁处理
- MySQL的并发控制与加锁分析
- MySQL的并发控制与加锁分析
- mysql的并发控制和加锁分析
- MySQL的并发控制和加锁分析
- PHP重定向的具体实现方式
- ios系统自带推送(ios自学笔记)
- Linux+Nginx+Tomcat 多域名,多应用在同一服务器的配置
- Java遍历列出某一目录下的文件及文件夹,寻找某一指定文件
- Cocos2d-x-3.6学习(三)---- TestCpp学习
- OpenGL ES2.0 基本编程
- [转]并发下常见的加锁及锁的PHP具体实现
- HDU 1011 Starship Troopers(树形dp+背包)
- 黑马程序员————第六天
- C#高级编程三十七天----结构比较
- 修改u-boot与Linux调试串口以及文件系统显示终端串口
- text
- Linux安装xwindow图形界面
- JFreechart 笔记一
- QByteArray通过QDataStream的读写