PHP文件锁封装备份代码

备份下代码

<?php

namespace Lib\Library;

use Closure;
use Exception;

/**

  • 文件锁
  • 1.阻塞,进程加锁时发现其他进程已经加锁会一直阻塞等待,一直等到可以加锁成功,然后去执行业务代码
  • 2.非阻塞,进程加锁时发现其他进程已经加锁直接返回,不会执行业务代码
  • 3.注意Erp默认Session驱动为文件,本身请求已经存Session锁机制,所以测试非阻塞时请修改Session驱动为Redis
  • @package Lib\Library

*/
class FileLock
{

/**
 * 锁文件位置
 * @var string
 */
private $file;

/**
 * 锁文件句柄
 * @var
 */
private $fileHandle;

/**
 * 构造函数
 * @param string $name 锁名称
 * @throws Exception
 */
public function __construct($name = 'lock')
{
    //初始化文件
    $path = RUNTIME_PATH . 'Lock' . DIRECTORY_SEPARATOR;
    $this->file = $path . md5($name);
    if (!is_dir($path)) {
        if (!mkdir($path, 0777, true)) {
            throw new Exception('文件锁目录创建失败,请检查目录' . $path . '是否可写');
        }
    }
    if (!file_exists($this->file)) {
        if (file_put_contents($this->file, '')) {
            throw new Exception('文件锁创建失败,请检查文件' . $this->file . '是否可写');
        }
    }
}

/**
 * 加锁
 * @param bool $block
 * @return bool
 */
public function lock($block = true)
{
    $this->fileHandle = fopen($this->file, 'r');
    $is_flock = $block ? flock($this->fileHandle, LOCK_EX) : flock($this->fileHandle, LOCK_EX | LOCK_NB);
    if (!$is_flock) {
        fclose($this->fileHandle);
    }
    return $is_flock;
}

/**
 * 释放
 */
public function release()
{
    if (!$this->fileHandle) {
        return false;
    }
    $unlock = flock($this->fileHandle, LOCK_UN);
    if ($unlock) {
        fclose($this->fileHandle);
        $this->fileHandle = null;
    }
    return $unlock;
}

/**
 * 加锁执行
 * @param Closure $func 执行闭包函数
 * @param bool $block 是否阻塞
 * @return mixed 闭包函数的返回值
 */
public function lockToExecute($func, $block = true)
{
    $is_flock = $this->lock($block);
    $call_back = null;
    if ($is_flock) {
        $call_back = $func();
        $this->release();
    }
    return $call_back;
}

}

×

上一篇:Apache RocketMQ核心技术与实战 丨讲师文章合集


下一篇:PolarDB-X 1.0-SQL 手册-运算符-比较运算符