Home  >  Article  >  Backend Development  >  PHP process lock related content

PHP process lock related content

一个新手
一个新手Original
2017-09-12 09:44:531194browse

<?php
/**
 * CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库
 * 用于解决PHP在并发时候的锁控制,通过文件/eaccelerator进行进程间锁定
 * 如果没有使用eaccelerator则进行进行文件锁处理,会做对应目录下产生对应粒度的锁
 * 使用了eaccelerator则在内存中处理,性能相对较高
 * 不同的锁之间并行执行,类似mysql innodb的行级锁
 * 本类在sunli的phplock的基础上做了少许修改  http://code.google.com/p/phplock
 * @author yangxinqi
 *
 */
namespace Common\Business;
class PhpLock
{
    //文件锁存放路径
    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=&#39;lock\\&#39;)
    {
        $app_path = str_replace(&#39;ThinkPHP/&#39;, &#39;&#39;, THINK_PATH);
        $is_cli = php_sapi_name();
        if($is_cli == &#39;cli&#39; || $is_cli == &#39;cli_server&#39;)
        {
            $app_path = trim(APP_PATH, &#39;.&#39;);
        }
        else
        {
            $app_path = $app_path . trim(APP_PATH, &#39;.&#39;);
        }

        $path = $app_path.&#39;/Common/Business/lockfile/&#39;;
        if(!file_exists($path))
        {
            mkdir($path);
            chmod($path,777);
        }
        //$path .= &#39;/protected/runtime/cache/&#39;;
        //判断是否存在eAccelerator,这里启用了eAccelerator之后可以进行内存锁提高效率
        $this->eAccelerator = function_exists("eaccelerator_lock");
        if(!$this->eAccelerator)
        {
            //$this->path = $path.($this->_mycrc32($name) % $this->hashNum).&#39;.txt&#39;;
            $this->path = $path.sha1($name).&#39;.txt&#39;;
        }
        $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, &#39;w+&#39;);
            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);
        }
    }
}

The above is the detailed content of PHP process lock related content. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn