PHP flock 函数
最后修改于 2025 年 4 月 3 日
PHP flock 函数提供咨询性文件锁定。它有助于防止多个进程访问同一文件时发生竞态条件。
基本定义
flock 函数允许您获取或释放对已打开文件的锁定。它作用于文件指针资源,并支持共享/独占锁定。
语法:flock(resource $stream, int $operation, int &$would_block = null): bool。该函数成功时返回 true,失败时返回 false。
基本独占锁定示例
此示例展示了如何获取独占锁定以写入文件。
basic_exclusive_lock.php
<?php
declare(strict_types=1);
$file = fopen("data.txt", "c+");
if (flock($file, LOCK_EX)) {
fwrite($file, "Writing with exclusive lock\n");
flock($file, LOCK_UN); // Release lock
} else {
echo "Couldn't get the lock!";
}
fclose($file);
此示例在写入前获取独占锁定 (LOCK_EX)。使用 LOCK_UN 释放锁定。一次只能有一个进程持有独占锁定。
共享锁定示例
此示例演示了使用共享锁定来安全地读取文件。
shared_lock.php
<?php
declare(strict_types=1);
$file = fopen("data.txt", "r");
if (flock($file, LOCK_SH)) {
$content = fread($file, filesize("data.txt"));
echo $content;
flock($file, LOCK_UN);
} else {
echo "Couldn't get the shared lock!";
}
fclose($file);
多个进程可以同时持有共享锁定 (LOCK_SH)。当您希望允许多个并发读取但防止在读取期间进行写入时,这很有用。
非阻塞锁定示例
此示例展示了如何尝试非阻塞锁定,如果不可用则立即失败。
non_blocking.php
<?php
declare(strict_types=1);
$file = fopen("data.txt", "c+");
if (flock($file, LOCK_EX | LOCK_NB, $would_block)) {
if ($would_block) {
echo "Lock is held by another process\n";
}
fwrite($file, "Non-blocking write\n");
flock($file, LOCK_UN);
} else {
echo "Couldn't get non-blocking lock!\n";
}
fclose($file);
LOCK_NB 标志使函数在无法获取锁定后立即返回。 $would_block 参数指示锁定是否因争用而失败。
带超时的文件锁定
此示例实现了获取锁定的简单超时机制。
lock_timeout.php
<?php
declare(strict_types=1);
function acquireLockWithTimeout($file, int $timeout = 5): bool {
$start = time();
while (!flock($file, LOCK_EX | LOCK_NB)) {
if (time() - $start >= $timeout) {
return false;
}
usleep(100000); // Wait 100ms before retry
}
return true;
}
$file = fopen("data.txt", "c+");
if (acquireLockWithTimeout($file)) {
fwrite($file, "Write with timeout lock\n");
flock($file, LOCK_UN);
} else {
echo "Failed to acquire lock within timeout\n";
}
fclose($file);
此示例通过反复尝试获取非阻塞锁定来实现自定义超时。它等待最多 5 秒后放弃。
进程同步示例
此示例演示了使用文件锁定进行进程间同步。
process_sync.php
<?php
declare(strict_types=1);
$lockFile = fopen("process.lock", "c+");
if (!flock($lockFile, LOCK_EX)) {
die("Could not acquire lock\n");
}
// Critical section
file_put_contents("output.log", "Process " . getmypid() . " running\n", FILE_APPEND);
sleep(2); // Simulate work
flock($lockFile, LOCK_UN);
fclose($lockFile);
echo "Process completed\n";
这确保了脚本一次只运行一个实例。锁定文件充当进程同步的互斥锁。
最佳实践
- 始终释放锁定:使用 try-finally 块确保解锁。
- 保持锁定时间短:尽量缩短持有锁定的时间。
- 处理错误:检查 flock 调用返回的值。
- 使用咨询性锁定:请记住 PHP 中的锁定是咨询性的。
- 清理:使用后关闭文件以释放资源。
来源
本教程涵盖了 PHP flock 函数,并提供了实际示例,展示了用于安全文件操作的文件锁定技术。
作者
列出 所有 PHP 文件系统函数。