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

PHP flock() 文件鎖獨占操作原理與實測詳解

     編輯:PHP 相關知識

flock() 函數基本語法

bool flock ( resource $handle, int $operation [, int &$wouldblock ] )

PHP 支援諮詢式文件鎖定,要求所有訪問進程必須使用相同鎖定方式才生效。

操作模式常量

常量值(舊版)說明
LOCK_SH1共享鎖(讀取進程)
LOCK_EX2獨占鎖(寫入進程)
LOCK_UN3釋放鎖(共享/獨占通用)
LOCK_NB4非阻塞模式(配合其他模式使用)

重要注意事項

  • Windows 下 flock() 強制執行
  • 需已打開的文件指標作為 handle
  • 寫模式(w/w+)開啟文件時需特殊鎖定文件保護
  • 不支援 NFS、網絡文件系統及 FAT 等舊文件系統
  • 多線程服務器(API如 ISAPI)下可能無法保護文件
  • 鎖可由 fclose() 或腳本結束自動釋放

獨占鎖測試案例

測試一:無限循環寫入對比

a.php 持有鎖持續寫入 a\n,b.php 嘗試寫入 b\n:

<?php
// a.php
if (!($f = @fopen("flock.log", "ab"))) exit;
flock($f, LOCK_EX);
while(TRUE) {
    fwrite($f, "a\n");
}
?>

<?php
// b.php
if (!($f = @fopen("flock.log", "ab"))) exit;
flock($f, LOCK_EX);
while(TRUE) {
    fwrite($f, "b\n");
}
?>

結果:b.php 內容未寫入成功,驗證獨占鎖阻塞機制有效。

測試二:有限次寫入與睡眠

flocka.php(加鎖版):

$file = 'temp.txt';
$fp = fopen($file, 'a');
if (flock($fp, LOCK_EX)) {
    for ($i = 0; $i < 5; $i++) {
        fwrite($fp, "11111111\n");
        sleep(1);
    }
    flock($fp, LOCK_UN);
}
fclose($fp);

flockb.php(加鎖版):

$file = 'temp.txt';
$fp = fopen($file, 'a');
if (flock($fp, LOCK_EX)) {
    for ($i = 0; $i < 5; $i++) {
        fwrite($fp, "22222222\n");
    }
    flock($fp, LOCK_UN);
}
fclose($fp);

執行順序:先運行 flocka.php,隨即運行 flockb.php

結果:flockb.php 等待 flocka.php 釋放鎖後才執行,輸出順序為 5 行 11111111 後接 5 行 22222222。

對照組:無鎖版本

同樣代碼但移除 flock() 調用,結果顯示兩進程交替寫入,數據混亂。

結論

flock() 獨占鎖(LOCK_EX)能有效序列化並發寫入操作,確保數據一致性。實際應用中務必配合 LOCK_UN 及時釋放鎖,避免死鎖或性能瓶頸。

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