php стекается, и fread, и fwrite


Я вижу, как люди используют стадо вот так:

if (!$fp = fopen($file_name, 'wb'))  
{  
    return FALSE;  
}  

if (flock($fp, LOCK_EX))  
{  
    fwrite($fp, serialize($data));  
    flock($fp, LOCK_UN);  
}

Также это:

if (!$fp = @fopen($file_name, 'rb'))  
{  
    return FALSE;  
}  

flock($fp, LOCK_SH);  

$data = '';  

if (filesize($file_name) > 0)  
{  
    $data = unserialize(fread($fp, filesize($file_name)));  
}  

Но разве нет шанса, что кто-то другой отредактирует файл между вызовом fopen и вызовом flock? и тот же вопрос для fread


ИЗМЕНИТЬ:
Чтобы прояснить, почему я спрашиваю об этом... Я основываю свой вопрос на коде здесь, В ситуации с кэшированием mysql, что может помешать 20 людям получить доступ к файлу одновременно, если все они смогут войти между фопеном и стадом?

Является ли этот код надежным?

Author: pilcrow, 2012-08-06

2 answers

Вы спрашиваете:

есть ли вероятность, что кто-то другой отредактирует файл между вызовом fopen и вызовом flock? и тот же вопрос для фрида

Да, нет, может быть. Короткий ответ: предположите "да" и действуйте осторожно.

Да, в этой традиционной блокировке на основе flock() просто рекомендуется , поэтому другие процессы (или даже тот же процесс) могут игнорировать блокировки. На практике это не проблема, так как flock() используется корректный клиентский код - вы не читаете, пока не получите LOCK_SH, и вы не пишете, если не получили LOCK_EX - файлы, относящиеся к конкретному приложению.

Нет, в том, что реализация PHP flock() может быть обязательной в определенных операционных системах, согласно документации , которая также может потребовать поддержки от файловой системы (например, как с манд опция под Linux). Таким образом, другие процессы не могли игнорировать эти блокировки.

Может быть, в что подсистема потоков в PHP 5 реализует некоторую блокировку бухгалтерского учета помимо того, что предусмотрено операционной системой. Это может, например, помешать одному и тому же процессу (но не другому) игнорировать свои собственные в противном случае рекомендательные блокировки. Поведение может некоторых удивить . Тем не менее, такого рода блокировка не будет обязательной между несвязанными процессами.

Для переносимости просто предположите самую слабую семантику ("да" выше) и ограничьте flock() хорошо себя вести код для файлов блокировки конкретного приложения, выбранных заранее.

 6
Author: pilcrow, 2012-08-06 02:29:54

Первый фрагмент защищен от ошибок, если вы не можете заблокировать файл, вы не пишете. Если кто-то другой редактировал файл между fopen() и flock(), ваш дескриптор файла будет указывать на последнее воплощение, поскольку fopen() привязывается к потоку, а не к "снимку".

Второй пример не гарантированно сработает, потому что возвращаемое значение flock() не проверено, поэтому, если вы не получили блокировку, последующий код будет выполнен в любом случае.

[редактировать] удалено утверждение, что блокировка чтения не имеет значения, на самом деле это имеет значение, как объяснено в комментариях ниже:)

 2
Author: favoretti, 2012-08-05 20:53:15