该文件锁达到的效果是:

PHP语言中:多个请求,在同一时间段内,访问同一段代码,改代码只能同时处理一个请求,其它的请求排队等候,等一个请求处理完后,再依次处理剩余的请求。

类似于Java的synchronized线程同步。

实现的步骤如下(使用过程中需要注意下文件锁所在路径需要有写权限):

1、编辑一个进程锁类CacheLock.class.php

<?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) {
            //配置目录权限可写 
            //echo $this -> path;
            //die();
            $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);
        }
    }
}
2、在 CacheLock.class.php文件的同级目录下新建一个lock的空文件夹

至此,已经配置完成。接下来就是测试使用。



3、分别建立讲个php文件index.php和index2.php。

index.php:

<?php
	require 'CacheLock.class.php';
	$lock = new CacheLock('key_name'); 
	/*	这里是要同步的代码块	开始	*/
	$lock->lock(); 
	for($a=1;$a<5;$a++){
		file_put_contents("test.txt", "***********第一个文件[" . $a . "].\n", FILE_APPEND);
		sleep(2);
		echo '正在写入第  ' . $a . '个文件。';
	}
	/*	这里是要同步的代码块	结束	*/
	$lock->unlock(); 
?>
index2.php:

<?php
	require 'CacheLock.class.php';
	$lock = new CacheLock('key_name'); 
	/*	这里是要同步的代码块	开始	*/
	$lock->lock(); 
	for($a=1;$a<5;$a++){
		file_put_contents("test.txt", "第二个文件[" . $a . "].\n", FILE_APPEND);
		sleep(2);
		echo '正在写入第  ' . $a . '个文件。';
	}
	/*	这里是要同步的代码块	结束	*/
	$lock->unlock(); 
?>

这两个文件代码几乎一模一样,只是输出文件(file_put_contents)的内容不一样,循环4次写入文件内容。

其中:$lock = new CacheLock('key_name');为关键,'key_name'就是要同步的标识,两个地方的'key_name'需要设置相同。

目录结构如下:


4、现在同时在浏览器中打开index.php和index2.php


执行完成以后可以看到目录下生成了一个text.txt文件


写入的顺序是第一个index.php中的代码执行完后才执行index2.php中的代码。达到了同步的效果。

Demo下载地址:http://download.csdn.net/detail/u014175572/9696452

参考前辈的文章:http://www.jb51.net/article/24962.htm

更多相关文章

  1. 一个简易的PHP读取CSV文件的方法
  2. PHP脚本在我的Wordpress文件中。请解码或帮助我删除它。
  3. 一个关于用php输出文件的问题(急)
  4. php中的文件包含
  5. 使用php浏览文件时,编写文件的完整路径
  6. php mail函数一段好的代码
  7. composer不能生成sf2 autoload文件。
  8. include一个php文件,经常会失败,请问需要注意些什么?
  9. nginx + fastcgi  php配置下,安全的文件上存路径设置

随机推荐

  1. 004. 寻找两个正序数组的中位数 | Leetco
  2. 自学编程的八大误区!克服它!
  3. webpack4配置详解之慢嚼细咽
  4. “狗屁不通文章生成器”项目登顶GitHub热
  5. 005. 最长回文子串 | Leetcode题解
  6. 大家好 这就是2018年的我~
  7. Linux环境都没有,怎么学编程?憋说了,肝!(保姆
  8. 006. Z 字形变换 | Leetcode题解
  9. eruda 一个被人遗忘的调试神器
  10. Linux性能优化(五)——性能监控工具