САМОУЧИТЕЛЬ PHP 4

Блокирование файла


При интенсивном обмене данными с файлами в мультизадачных операционных системах встает вопрос синхронизации операций чтения/записи между процессами. Например, пусть у нас есть несколько "процессов-писателей"

и один "процесс-читатель". Необходимо, чтобы в единицу времени к файлу имел доступ лишь один процесс-писатель, а остальные на этот момент времени как бы "подвисали", ожидая своей очереди. Это нужно, например, чтобы данные от нескольких процессов не перемешивались в файле, а следовали блок за блоком. Как мы можем этого достигнуть?

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

Однажды я прочитал одно замечательное сравнение рекомендательной блокировки с перекрестком, на котором установилось довольно оживленное движение, регулируемое светофором. Когда горит красный, одни машины стоят, а другие проезжают. В принципе, любая машина может, так сказать, проехать наперекор правилам дорожного движения, не дожидаясь зеленого сигнала, но в таком случае возможны аварии. Рекомендательная блокировка работает точно таким же образом. А именно, процессы, которые ей пользуются, будут работать с разделяемым файлом правильно, а остальные… как-нибудь да будут, пока не произойдет "столкновение".

С другой стороны, "жесткая блокировка"

(которая в PHP не поддерживается) подобна шлагбауму: никто не сможет проехать, пока его не поднимут.

О жесткой блокировке мы в этой книге говорить не будем.

Единственная функция, которая занимается управлением блокировками в PHP, называется flock().

bool flock(int $f, int $operation [, int& $wouldblock])

Функция устанавливает для указанного открытого дескриптора файла $f режим блокировки, который бы хотел получить текущий процесс. Этот режим задается аргументом $operation и может быть одной из следующих констант:


r    LOCK_SH (или 1) — разделяемая блокировка;

r    LOCK_EX (или 2) — исключительная блокировка;

r    LOCK_UN (или 3) — снять блокировку;

r    LOCK_NB (или 4) — эту константу нужно прибавить к одной из предыдущих, если вы не хотите, чтобы программа "подвисала" на flock() в ожидании своей очереди, а сразу возвращала управление.

В случае, если был затребован режим без ожидания, и блокировка не была успешно установлена, в необязательный параметр-переменную $wouldblock будет записано значение истина true.

В случае ошибки функция, как всегда, возвращает false, а в случае успешного завершения — true.



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


Содержание раздела