Флок блокирует файл между процессами? - PullRequest
1 голос
/ 07 апреля 2019

Следующий код вызывает ошибку, хотя и очень редко, при вызове 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?

1 Ответ

0 голосов
/ 07 апреля 2019

В системах Linux (и других UNIX) flock() является чисто рекомендательной блокировкой.Это не позволит другим процессам получить конфликтующую блокировку для того же файла с flock(), но не предотвратит изменение или удаление файла.

В системах Windows flock() является обязательной блокировкой,и предотвратит изменения в файле.

...