文档章节

PHP并发操作下的加锁

qimh
 qimh
发布于 2016/11/17 17:09
字数 670
阅读 46
收藏 0

代码如下:

文件锁类

<?php
/**
 * CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库
 * 用于解决PHP在并发时候的锁控制,通过文件/eaccelerator进行进程间锁定
 * 如果没有使用eaccelerator则进行进行文件锁处理,会做对应目录下产生对应粒度的锁
 * 使用了eaccelerator则在内存中处理,性能相对较高
 * 不同的锁之间并行执行,类似mysql innodb的行级锁
 * 本类在sunli的phplock的基础上做了少许修改  http://code.google.com/p/phplock 
 * @author yangxinqi
 *
 */
class b2c_test_cachelock extends b2c_api_rpc_request{
    //文件锁存放路径
    private $path = null;
    //文件句柄
    private $fp = null;
    //锁粒度,设置越大粒度越小
    private $hashNum = 100;
    //cache key 
    private $name;
    //是否存在eaccelerator标志
    private  $eAccelerator = false;
    public $num = 10;
    
    /**
     * 构造函数
     * 传入锁的存放路径,及cache key的名称,这样可以进行并发
     * @param string $path 锁的存放目录,以"/"结尾
     * @param string $name cache key
     */
    public function __construct($name,$path='lock\\')
    {
        //echo "构造方法被执行......";
        //echo $name;
        //echo $path;
        $name = "key_name";
        $path = "D:\\WWW\\ecstore\\data\\lock\\";
        //判断是否存在eAccelerator,这里启用了eAccelerator之后可以进行内存锁提高效率
        $this->eAccelerator = function_exists("eaccelerator_lock");
        if(!$this->eAccelerator)
        {
            $this->path = $path.($this->_mycrc32($name) % $this->hashNum).'.txt';
            //echo "fine name:".$this->path."<br>";
        }
        $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);
        }
    }
}

?>
 

 

 

使用如下:

并发提供的接口
    //测试线程并发----测试通过解决线程并发问题
    public function fileLock(){
        $lock = kernel::single("b2c_test_cachelock");//实例化类也可以这样:$lock = new CacheLock('key_name',"D:\\WWW\\ecstore\\data\\lock\\");
        $lock->lock();//文件加锁
        //logic  如下:
        //链接数据库
        //数据库sdb_b2c_cart_objects表测试记录:obj_ident=1    member_ident=10    member=10    obj_type=goods    params=21    quantity=100    
        $conn = Mysql::mysqlConnection();//获取数据连接,这里连接你们自己的数据库
        $sql = "select quantity from sdb_b2c_cart_objects where obj_ident = 1 ";
        $result = mysql_query($sql,$conn);
        
        $quantity = 0;
        while($row = mysql_fetch_array($result,MYSQL_ASSOC)){
            $quantity= $row['quantity'];
        }
        sleep(1);//休眠一秒钟
        //logic here
        if($quantity > 0){
            //echo $lock->num;
            
            $quantity -- ;
            ToolKit::_myLogln("数量:",$quantity,LOG_DIR."fileLock");//打印日志,可以删除
            echo $quantity;
            $update_sql = 'update sdb_b2c_cart_objects set quantity = "'.$quantity.'" where obj_ident = 1';
            mysql_query($update_sql);
        }
        $lock->unlock();//文件解锁
        //使用过程中需要注意下文件锁所在路径需要有写权限.
    }

 

 

转自这篇博客:http://www.nowamagic.net/php/php_LockInConcurrent.php

 

© 著作权归作者所有

共有 人打赏支持
qimh
粉丝 9
博文 388
码字总数 69511
作品 0
滁州
程序员
私信 提问
inhere/php-queue

php 的队列实现 php的队列使用包装, 默认自带支持 三个级别的队列操作。 基于数据库(mysql/sqlite)的队列实现 基于 php 实现 基于 redis 实现 - 操作具有原子性,并发操作不会有问题 基于共享...

inhere
2017/06/13
0
0
Go实例讲解,并发编程-slice并发读写的线程安全性问题

先上实例代码,后面再来详细讲解。 /** * 并发编程,切片的线程安全性问题 */package main import ( "fmt" "sync" "time") var list []int = []int{}var wgList sync.WaitGroup = sync.Wait...

一凡Sir
08/14
0
0
使用mysql中的锁解决高并发问题

为什么要加锁 多核计算机的出现,计算机实现真正并行计算,可以在同一时刻,执行多个任务。在多线程编程中,因为线程执行顺序不可控导致的数据错误。比如,多线程的理想状态是这样的 但是实际情...

紫葡萄0
11/23
0
0
ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

TonyStarkSir
11/13
0
0
多线程——探索 ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

亚特兰缇斯
2015/09/08
231
0

没有更多内容

加载失败,请刷新页面

加载更多

GraphQL 基金会成立了:将托管于Linux 基金会管理

GraphQL 基金会在11月7日宣布成立,并将由 Linux 基金会管理。GraphQL 基金会将专用于完善和稳定 GraphQL 生态系统,让 GraphQL 得到广泛关注和采用。GraphQL 是 Facebook 开发的一个应用层数...

Linux就该这么学
10分钟前
2
0
Java开发中内存模型详细解析

Java内存模型虽说是一个老生常谈的问题 ,也是大厂面试中绕不过的,甚至初级面试也会问到。但是真正要理解起来,还是相当困难,主要这个东西看不见,摸不着。网上已经有大量的博客,但是人家...

金铭鼎IT教育
13分钟前
2
0
render常用模版 结合iview

表格添加一对按钮 { title: '操作', align: 'center', render: (h, params) => { return h('div', [ h('Button', { props: { ......

Carbenson
30分钟前
1
0
一次生产 CPU 100% 排查优化实践

前言 到了年底果然都不太平,最近又收到了运维报警:表示有些服务器负载非常高,让我们定位问题。 还真是想什么来什么,前些天还故意把某些服务器的负载提高(没错,老板让我写个 BUG!),不...

crossoverJie
37分钟前
8
0
Spring Cloud Alibaba Sentinel 整合 Feign 的设计实现

作者 | Spring Cloud Alibaba 高级开发工程师洛夜 来自公众号阿里巴巴中间件投稿 前段时间 Hystrix 宣布不再维护之后(Hystrix 停止开发。。。Spring Cloud 何去何从?),Feign 作为一个跟 ...

Java技术栈
53分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部