PHP在并发下的锁处理
来源:互联网 发布:什么是优化推广 编辑:程序博客网 时间:2024/06/07 19:44
PHP在多并发的web访问由于没有内置的锁支持,在处理一些资源的之后,很容易出现并发性问题。
在web开发中我们经常对我们的数据库耗时操作做缓存,但是可能出现一个陷阱,在缓存失效的一瞬间,大量
的访问得到缓存失效的标示,都去后端查询数据库,导致同时大量的数据库耗时查询,出现数据库宕机等问题。
此问题隐藏深,不容易查找。本项目主要用于解决php的进程间锁问题。
<?php/** * 测试例子,同时打开两个页面,可以发现总是同时只能一个页面进入到锁区间的代码 * @link http://code.google.com/p/phplock/ * @author sunli * @blog http://sunli.cnblogs.com * @svnversion $Id: test.php 4 2009-11-25 05:05:13Z sunli1223 $ * @version v1.0 beta1 * @license Apache License Version 2.0 * @copyright sunli1223@gmail.com */require 'class.phplock.php';$lock = new PHPLock ( 'lock/', 'lockname' );$lock->startLock ();$status = $lock->Lock ();if (! $status) { exit ( "lock error" );}echo increment ();$lock->unlock ();$lock->endLock ();function increment() { if (! file_exists ( 'testlockfile' )) { file_put_contents ( 'testlockfile', 0 ); } $num = file_get_contents ( 'testlockfile' ); $num = $num + 1; file_put_contents ( 'testlockfile', $num ); return file_get_contents ( 'testlockfile' );}/** * cache操作 * * @return $array */function getCache($key) { return $cache;}/** * 设置缓存 * * @param string $key * @param array $value */function setCache($key, $value) {}$key = 'cachekey';$cache = getCache ( $key );if (! $cache) { //缓存不存在,开始加锁 $lock = new PHPLock ( 'lock/', $key ); $lock->startLock (); $lock->Lock (); //尝试判断缓存是否有数据,可能已经有访问重建缓存了,就不需要再次查询数据库 $cache = getCache ( $key ); if (! $cache) { //数据库查询操作,代码省略了 $data = $dbdata; setCache ( $key, $data ); } //释放锁 $lock->unlock (); $lock->endLock ();}?>
在最近的项目中有这样的场景:
①、生成文件的时候,由于多用户都有权限进行生成,防止并发下,导致生成的结果出现错误,需要对生成的过程
进行加锁,只容许一个用户在一个时间内进行操作,这个时候就需要用到锁了,将这个操作过程锁起来.
②、在用了cache的时候,cache失效可能导致瞬间的多数并发请求穿透到数据库此时也可以得需要用锁在同一
并发的过程中将这个操作锁定.
使用如下:$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); } }}
- PHP在并发下的锁处理
- ArrayOf_xsd_string格式在php下的处理
- PHP中的uniqid在高并发下的重复问题
- PHP中的uniqid在高并发下的重复问题
- linux下的并发处理
- 备忘:Windows下php-cgi不能处理并发PHP请求
- 高并发下PHP请求Redis异常处理
- 高并发下PHP请求Redis异常处理
- php并发处理
- php并发处理
- php 多线程并发处理
- 如何在异步处理提高并发的情况下保持100%可靠?
- 【转】并发场景下的中断处理
- 几种高并发下写的处理策略
- MySQL + PHP的模式在大并发压力下导致MySQL中存在大量僵死进程
- 记录PHP、MySQL在高并发场景下产生的一次事故
- PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
- PHP和Redis实现在高并发下的抢购及秒杀功能
- 黑马程序员————高新技术————JDK1.5新特性
- 一道Google笔试题--关于预编译
- windows 下adb不能找到Android设备
- spring @Autowired使用
- javascriptIE浏览器一个控件的检测过程
- PHP在并发下的锁处理
- Win7安装64位CentOS 6.4双系统详细过程
- 2013年9月1日
- 我的第一个 Mono for Android 应用
- css中position的定位以及图片文字位置
- 关于QQ微博收费皮肤免费使用
- 初学Android,多媒体之使用SoundPool播放音效
- (step8.2.4)hdu 1846(Brave Game——巴什博奕)
- 变量的声明与定义“extern”