14.2.3. Блокирование BSD: flock()
14.2.3. Блокирование BSD: flock()
4.2 BSD представило свой собственный механизм блокировки, flock()[155]. Функция объявлена следующим образом:
#include <sys/file.h> /* Обычный */
int flock(int fd, int operation);
Дескриптор fd представляет открытый файл. Имеются следующие операции:
LOCK_SH Создает совместную блокировку. Может быть несколько совместных блокировок.
LOCK_EX Создает исключительную блокировку. Может быть лишь одна такая блокировка.
LOCK_UN Удаляет предыдущую блокировку.
LOCK_NB При использовании побитового ИЛИ с LOCK_SH или LOCK_EX позволяет избежать блокирования функции, если блокировка файла невозможна.
По умолчанию запросы блокировки файла будут блокировать функцию (не давать ей вернуться), если существует конкурирующая блокировка. Запрашивающая функция возвращается, когда конкурирующая блокировка файла снимается и осуществляется запрошенная функцией блокировка файла. (Это предполагает, что по умолчанию имеется возможность возникновения тупика.) Чтобы попытаться заблокировать файл без блокирования функции, добавьте посредством побитового ИЛИ значение LOCK_NB к имеющемуся значению operation.
Отличительными моментами flock() являются следующие:
• Блокировка с помощью flock() является вспомогательной; программа, не использующая блокировку, может прийти и испортить без всяких сообщений об ошибках файл, заблокированный с помощью flock().
• Блокируется весь файл. Нет механизма для блокировки только части файла.
• То, как был открыт файл, не влияет на тип блокировки, который может быть использован. (Сравните это с fcntl(), при использовании которой файл должен быть открыт для чтения для получения блокировки чтения, или для записи для блокировки записи.)
• Несколько открытых для одного и того же файла дескрипторов используют совместную блокировку. Для удаления блокировки может использоваться любой из них. В отличие от fcntl(), когда нет явного разблокирования, блокировка не удаляется до тех пор, пока не будут закрыты все открытые дескрипторы файла.
• Процесс может иметь лишь одну блокировку файла с помощью flock(); последовательный вызов flock() с двумя различными типами блокировок изменяет тип блокировки на новый.
• На системах GNU/Linux блокировки flock() совершенно независимы от блокировок fcntl(). Многие коммерческие системы Unix реализуют flock() в виде «оболочки» поверх fcntl(), но их семантика различается.
Мы не рекомендуем использовать flock() в новых программах, поскольку ее семантика не такая гибкая и поскольку она не стандартизована POSIX. Поддержка ее в GNU/Linux осуществляется главным образом для обратной совместимости с программным обеспечением, написанным для старых систем BSD Unix.
ЗАМЕЧАНИЕ. Справочная страница GNU/Linux flock(2) предупреждает, что блокировки flock() не работают для смонтированных удаленных файлов. Блокировки fcntl() работают, при условии, что у вас достаточно новая версия Linux и сервер NFS поддерживает блокировки файлов