我需要打开一个日志文件进行写入。麻烦的是,很多事情可能会同时发生,我不想要冲突。每次写入将是一行,通常大约 150 字节(并且总是小于 1K),并且不严格要求按时间顺序排列。
我想我想要的是尝试flock()
,如果失败,请继续尝试几秒钟。如果多次尝试后仍无法建立锁,则放弃。
$fh=fopen($logfile, "a");
if (flock($fh, LOCK_EX|LOCK_NB)) {
$locked=TRUE;
} else {
$locked=FALSE;
// Retry lock every 0.1 seconds for 3 seconds...
$x=0; while($x++ < 30) {
usleep(100000);
if (flock($fh, LOCK_EX|LOCK_NB)) {
$locked=TRUE;
break;
}
}
}
if ($locked) {
if (fwrite($fh, strftime("[%Y-%m-%d %T] ") . $logdata . "\n")) {
print "Success.\n";
} else {
print "Fail.\n";
}
flock($fh, LOCK_UN)
} else {
print "Lock failed.\n";
}
我有两个问题,一个是一般的,一个是具体的。首先,除了以不同的方式(do...while
等)实现相同的解决方案之外,是否有更好的通用策略来处理此类问题,仅在 PHP 中运行?其次,有没有更好的方法在 PHP 中实现这一点?(是的,我把它们分开是因为我对策略部分真的很感兴趣。)
我考虑过的一种替代方法是使用syslog(),但 PHP 代码可能需要在系统级管理(即向 /etc/syslog.conf 中添加内容)可能无法作为选项提供的平台上运行。
更新:根据randy的建议添加|LOCK_NB
到上面的代码中。