文档章节

PHP并发操作下的加锁

qimh
 qimh
发布于 2016/11/17 17:09
字数 670
阅读 39
收藏 0
点赞 0
评论 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
粉丝 7
博文 280
码字总数 50260
作品 0
滁州
程序员
inhere/php-queue

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

inhere ⋅ 2017/06/13 ⋅ 0

php redis实现秒杀功能

主要针对并发情况下,通过redis的分布式锁和队列的方式进行处理的代码 Queue:{商品ID}: 数据类型是有序集合(zset),成员是用户ID,score是用户入队的时间戳 Lock:Queue:{商品ID}: 数据类型...

RitaChen ⋅ 2016/11/17 ⋅ 0

多线程——探索 ConcurrentHashMap 高并发性的实现机制

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

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

phpPOST发送图片上传到临时目录如何设置手工删除

各位大佬好,如果平时我们表单上传文件时会先把文件上传到临时目录,然后用moveupoladfile 移动文件到指定目录,而临时文件则会再进程结束之后回收删除,现在我的业务需求是会上传很多文件,涉...

IT囚徒 ⋅ 2017/03/26 ⋅ 1

并发编程(三):同步容器和并发容器

前言 Java 中有些集合和非线程安全,而有些集合是线程安全,后者又被称为是Java中的同步容器,因为它能满足操作的原子性,保持数据同步。有些容器时Java自带的,而有些是通过Collections提供...

mengdonghui123456 ⋅ 2017/08/15 ⋅ 0

MySQL · 源码分析 · Query Cache并发处理

Query cache 的并发处理 上期介绍了Query cache的一个基本工作原理,请参考MySQL · 源码分析 · Query Cache内部剖析。本期将对Query cache的并发处理过程进行一个剖析。 当前Query cache是...

阿里云RDS-数据库内核组 ⋅ 2016/08/10 ⋅ 0

ConcurrentHashMap源码分析

前言 JDK中的Hashtable是一个线程安全的K-V形式的容器,它实现线程安全的原理十分简单,就是在所有涉及对该哈希表操作的方法上都加上了synchronized关键字,进行加锁操作。这么做实现了线程安...

Justlearn ⋅ 2017/04/13 ⋅ 0

ConcurrentHashMap实现机制

Java 内存模型 由于 ConcurrentHashMap 是建立在 Java 内存模型基础上的,为了更好的理解 ConcurrentHashMap,让我们首先来了解一下 Java 的内存模型。 Java 语言的内存模型由一些规则组成,...

zhangchd ⋅ 2015/04/28 ⋅ 0

java并发编程实战------阅读笔记第五章基础构建模块

一、同步容器类1、早期的同步容器类Vector ,Hashtable,类似于Collections.synchronizedXxxx方法创建的,就是用装饰器模式把线程不安全的容器类包装起来,所有公共方法都进行同步,这种容器...

treenewtreenew ⋅ 2016/11/02 ⋅ 0

事务并发的可能问题与其解决方案

一、多个事务并发时可能遇到的问题 Lost Update 更新丢失 a. 第一类更新丢失,回滚覆盖:撤消一个事务时,在该事务内的写操作要回滚,把其它已提交的事务写入的数据覆盖了。b. 第二类更新丢失...

傅易 ⋅ 2016/11/20 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vim编辑模式、命令模式

编辑模式 vim要从一般模式进入编辑模式只要按字母 i 、I、a、A、o、O键就可以了 要从编辑模式回到一般模式按键盘上的Esc键即可。 按键 作用 i 在当前字符前插入 I 在光标所在行的行首插入 o ...

黄昏残影 ⋅ 27分钟前 ⋅ 0

OSChina 周五乱弹 —— 如果有一天不当程序员了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享off的单曲《我唱情歌给你听》 《我唱情歌给你听》- off 手机党少年们想听歌,请使劲儿戳(这里) @小小编辑 :#如果不做程序...

小小编辑 ⋅ 33分钟前 ⋅ 4

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

Java8新增的DateTimeFormatter与SimpleDateFormat的区别

两者最大的区别是,Java8的DateTimeFormatter也是线程安全的,而SimpleDateFormat并不是线程安全。 在并发环境下使用SimpleDateFormat 为了能够在多线程环境下使用SimpleDateFormat,有这三种...

人觉非常君 ⋅ 今天 ⋅ 0

多线程如何控制执行顺序

线程的生命周期说明: 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、...

MarinJ_Shao ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Django第一期

安装Django 去https://www.djangoproject.com/download/ 下载最新版的Django,然后解压放到Anaconda\Lib\site-packages目录下,然后cmd进入此目录,输入安装命令: python setup.py install ...

大不了敲一辈子代码 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部