Мне нужно открыть файл журнала для записи. Проблема в том, что многие вещи могут делать это одновременно, а я не хочу конфликтов. Каждая запись будет состоять из одной строки, обычно около 150 байт (и всегда меньше 1 КБ ), и упорядочение в хронологическом порядке строго не требуется.
Я думаю, что я хочу, так это попытаться 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 ), может быть недоступно в качестве опции.
ОБНОВЛЕНИЕ:добавлен |LOCK_NB
к приведенному выше коду по предложению randy .