首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 檔案鎖定機制實作:flock() 獨佔鎖與非阻塞模式完整封裝

     編輯:PHP 綜合知識

提供生產級的 PHP 檔案鎖定函數庫,支援阻塞/非阻塞模式、自動清理鎖檔、資源釋放,適用於多行程環境下的關鍵區段保護、排程任務防重複執行等場景。

核心函數:lock_thisfile()

function lock_thisfile($tmpFileStr, $locktype = false) {
    // $locktype: false=非阻塞(LOCK_EX|LOCK_NB), true=阻塞(LOCK_EX)
    if ($locktype === false) $locktype = LOCK_EX | LOCK_NB;

    $lockfp = @fopen($tmpFileStr . ".lock", "w");
    if (!$lockfp) return false;

    $can_write = @flock($lockfp, $locktype);
    if ($can_write) return $lockfp; // 回傳檔案指標供解鎖使用

    // 取得鎖失敗:清理資源
    @fclose($lockfp);
    @unlink($tmpFileStr . ".lock");
    return false;
}

解鎖函數:unlock_thisfile()

function unlock_thisfile($fp, $tmpFileStr) {
    @flock($fp, LOCK_UN);   // 釋放鎖
    @fclose($fp);           // 關閉檔案指標
    @unlink($tmpFileStr . ".lock"); // 刪除鎖檔
}

使用範例

<?php
$tmpFileStr = "/tmp/mylock.loc";

// 阻塞模式:等待直到取得鎖
$lockhandle = lock_thisfile($tmpFileStr, true);
if ($lockhandle) {
    // === 關鍵區段開始 ===
    // 執行獨佔操作:寫入檔案、資料庫交易、API 呼叫等
    // === 關鍵區段結束 ===
    unlock_thisfile($lockhandle, $tmpFileStr);
} else {
    echo "無法取得鎖,可能有其他行程正在執行";
}
?>

參數與模式對照

模式第二參數flock 旗標行為
非阻塞false (預設)LOCK_EX | LOCK_NB立即回傳 false 若鎖被佔用
阻塞trueLOCK_EX等待直到取得鎖

適用場景

  • 排程任務防重複(如每分鐘跑一次,防止上一次未結束)
  • 多行程寫入同一檔案/資料表
  • 外部 API 限流呼叫的同步控制
  • 快取重建的單一執行保護

注意事項

  1. 鎖檔建議放在 /tmp 或專用目錄,避免權限問題。
  2. Nfs 掛載檔案系統 flock() 可能不可靠,需改用資料庫鎖或 Redis 分散式鎖。
  3. PHP 程式異常終止時,鎖檔可能殘留,建議啟動時清理過期鎖檔。
  4. Windows 平台 flock() 為強制鎖,行為與 Linux 建議鎖略有不同。

將檔案鎖封裝為可重用函數,能有效簡化併發控制邏輯,提升系統穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved