zoukankan      html  css  js  c++  java
  • PHP并发操作下的加锁

    最近做后台统计的工具,统计肯定是一个需要运算好久的数据

    容许一个用户在一个时间内进行操作,这个时候就需要用到锁了,将这个操作过程锁起来。在用了cache的时候,cache失效可能导致瞬间的多数并发请求穿透到数据库此时也可以得需要用锁在同一并发的过程中将这个操作锁定

    你也可以改用XCache 来写

    <?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 判断字符串是否以某字符串结尾的方法
    且看新手如何快速新站优化(经验+求指导+找喷) 西安
    xml 序列化和反序列化 西安
    反射+xml 序列化 实际应用 西安
    使用自定义文件缓存提升ASP.NET项目性能 西安
    反射的简单应用(记录) 西安
    java web 中的 controller、service、persistence(mapper)、domain 分别是什么作用?
    nodesass 替换为 sass
    github 访问不了 访问 github,修改 hosts 文件方法
    win10 如何使用管理员权限编辑文件
  • 原文地址:https://www.cnblogs.com/jackluo/p/3382095.html
Copyright © 2011-2022 走看看