PHP并发进程锁

实现原理 利用flock()函数对文件使用锁定机制(锁定或释放文件)。当一个进程在访问文件时加上锁,其他进程要想对该文件进行访问,则必须等到锁定被释放以后。这样就可以避免在并发访问同一个文件时破坏数据。实现并发按序进行。

创建文件进程锁类

<?php
/**
 * Created by PhpStorm.
 * User: Pasa吴
 * Date: 2022/8/19
 * Time: 21:18
 */

namespace tools;


/**
 * 文件进程锁类
 * Class Process
 * @package tools
 */
class Process
{
    protected $dir = '';        // 锁文件存放目录
    protected $o_file;
    private static $instance;

    public function __construct()
    {
        $this->dir = runtime_path() . 'lock/';
        if (!is_dir($this->dir) && !file_exists($this->dir)) {
            mkdir($this->dir);
        }
    }

    /**
     * 单例模式
     * @return Process
     */
    public static function instance()
    {
        if (empty(self::$instance)) {
            self::$instance = new Process();
        }
        return self::$instance;
    }

    /**
     * 阻塞锁,已锁则暂停程序等待获得锁
     * @param string $key
     * @return bool
     */
    public function clogLock($key = 'lock')
    {
        $p_file       = $this->dir . $key . '.txt';
        $this->o_file = fopen($p_file, 'w+');
        // 如果临时文件被锁定,这里的flock()将返回false
        if (flock($this->o_file, LOCK_EX)) {
            return true;
        }
    }

    /**
     * 非阻塞锁,已锁则直接跳出
     * @param string $key
     * @return bool
     */
    public function flock($key = 'lock')
    {
        $p_file       = $this->dir . $key . '.txt';
        $this->o_file = fopen($p_file, 'w+');
        // 如果临时文件被锁定,这里的flock()将返回false
        if (!flock($this->o_file, LOCK_EX + LOCK_NB)) {
            return false;
        } else {
            return true;
        }
    }
}

使用方法


<?php
/**
 * Created by PhpStorm.
 * User: Pasa吴
 * Date: 2022/8/19
 * Time: 21:39
 */

namespace app\api\controller;


use tools\Process;

class Test
{
    /**
     * 进程锁案例
     */
    public function test()
    {
        $id = '1';//id可以是商品ID,规格ID,活动ID,秒杀ID,等等 业务逻辑唯一标识符
        Process::instance()->clogLock('product_id_' . $id);
        //TODO 处理业务逻辑
    }

}


Pasa吴技术博客
请先登录后发表评论
  • latest comments
  • 总共0条评论