flock() 提供跨平台的文件级建议性锁,是 PHP 处理多进程并发读写文件的核心工具。本文深入解析锁模式、阻塞与非阻塞策略,并给出生产级「重试写入」封装函数。
bool flock ( resource $handle , int $operation [, int &$wouldblock ] )
LOCK_SH(共享锁/读锁):多进程可同时持有,写锁会被阻塞。LOCK_EX(独占锁/写锁):同一时间仅一个进程持有,读写锁均阻塞。LOCK_UN:释放锁。LOCK_NB:非阻塞模式(与上述按位或),无法获取锁立即返回 false,不等待。 0) {
usleep(rand(1, 10000)); // 随机微秒延迟,降低冲突概率
}
$retries++;
} while (!flock($fp, LOCK_EX) && $retries <= $max_retries);
if ($retries > $max_retries) {
fclose($fp);
return false;
}
fwrite($fp, "$data\n");
flock($fp, LOCK_UN);
fclose($fp);
return true;
}
?>
fclose() 会自动释放锁,脚本结束也会自动释放,但显式 flock($fp, LOCK_UN) 更规范。flock 仅支持 LOCK_EX,不区分共享/独占。flock 支持不一,高并发场景建议改用 Redis 分布式锁或数据库行锁。合理使用文件锁,可有效解决定时任务、爬虫、日志写入等场景的并发冲突问题。