Следующий код вызывает ошибку, хотя и очень редко, при вызове file_get_contents
, что файл не существует, хотя file_exists
вызывался всего несколькими операторами выше.
Я считаю, что файл был удален заданием cron между моментом вызова file_exists
и возникновением ошибки.
$isRead = self::FILE_READ === $action;
$exists = file_exists($file);
$handle = fopen($file, ($isRead ? 'r' : 'c+'));
if ($handle) {
$locked = flock($handle, ($isRead ? LOCK_SH : LOCK_EX));
if ($locked) {
if ($exists) {
// Sometimes (very rarely) the following line triggers an error that
// $file does not exist
$data = (int)file_get_contents($file);
} else {
$data = 0;
}
if ($isRead) {
// Get Counter
flock($handle, LOCK_UN);
return $data;
}
// Update Counter
if (self::FILE_UPDATE === $action) {
$value += $data;
}
ftruncate($handle, 0);
rewind($handle);
fwrite($handle, $value);
flock($handle, LOCK_UN);
return true;
}
trigger_error("[FileCache] Failed to acquire lock for updating ${file}", E_USER_ERROR);
} else {
trigger_error("[FileCache] Failed to open file ${file}", E_USER_ERROR);
}
Гарантирует ли flock в PHP, что файл не будет изменен никакими другими процессами? Или это ограничивается текущим процессом?
Кроме того, делает ли unlink
в php честь flock
?
В системах Linux (и других UNIX) flock()
является чисто рекомендательной блокировкой. Это предотвратит получение другими процессами конфликтующей блокировки того же файла с помощью flock()
, но не предотвратит изменение или удаление файла.
В системах Windows flock()
является обязательной блокировкой и предотвращает изменение файла.
Мой ответ о внутренностях PHP. Единственная часть PHP, которая использует flock()
, — это flock()
.
Спасибо. Но мой вопрос был о внутренностях PHP. Учитывает ли интерпретатор php блокировку другого процесса?