bool flock ( resource $handle, int $operation [, int &$wouldblock ] )
PHP 支援諮詢式文件鎖定,要求所有訪問進程必須使用相同鎖定方式才生效。
| 常量 | 值(舊版) | 說明 |
|---|---|---|
| LOCK_SH | 1 | 共享鎖(讀取進程) |
| LOCK_EX | 2 | 獨占鎖(寫入進程) |
| LOCK_UN | 3 | 釋放鎖(共享/獨占通用) |
| LOCK_NB | 4 | 非阻塞模式(配合其他模式使用) |
w/w+)開啟文件時需特殊鎖定文件保護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 及時釋放鎖,避免死鎖或性能瓶頸。