php文件鎖實例

<?php
namespace App\Tools;

use Log;
use Exception;

//command 文件鎖  command執行完畢會釋放
class CmdLock
{
    public function __construct($called_class)
    {
        $lanmao_lock_path                   = sys_get_temp_dir() . '/lanmao_lock';
        if (!is_dir($lanmao_lock_path)) {
            mkdir($lanmao_lock_path);
        }

        $this->called_class         = $called_class;
        $class_info                 = explode('\\', $called_class);
        $this->class                = end($class_info);
        $this->lockname             = $this->class . '.lock';
        $this->lock_path            = $lanmao_lock_path . '/';
        $this->lock_realpath        = $this->lock_path . $this->lockname;
        $this->lock                 = fopen($this->lock_realpath, 'w+');
    }

    public function lock()
    {
        $date = date("Ymd H:i:s", time(null));
        $msg  = "command: {$this->class} ========> 準備加鎖";
        Log::info($msg);

        if (flock($this->lock, LOCK_EX | LOCK_NB)) {
            Log::info("command: {$this->class} ========> 鎖定...");
            return true;
        }

        throw new Exception('加鎖失敗!  ===>  ' . $this->called_class);
    }

    public function unlock()
    {
        $msg = "command: {$this->class} ========> 準備釋放鎖";

        Log::info($msg);

        flock($this->lock, LOCK_UN);
        fclose($this->lock);
    }
}

(執行腳本前需要創建  相應的lock文件  利用flock  對已經存在的文件進行鎖控制)

 

以前加鎖做法是  通過創建 一個 xxx.lock文件 確認加鎖 執行完畢 刪除xxx.lock

這種做法有個弊端就是,併發的情況下,如果程序拋出異常 會導致lock一直掛在那  無法解鎖

 

現在的加鎖方案是 利用linux  flock 加鎖機制  可以考慮 阻塞 和非阻塞的模式 。即使拋異常 也不影響 下次執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章