Вспомогательная блокировка (advisory lock) тесно соответствует замку на двери. Говорят, «замки существуют для честных людей», что означает, что если кто-нибудь
Обязательная блокировка является более строгой: когда установлена обязательная блокировка, ни один другой процесс не может получить доступ к заблокированному файлу. Любой процесс, который пытается игнорировать это, либо сам блокируется до снятия блокировки файла, либо его попытка завершится неудачей. (Под GNU/Linux по крайней мере это включает root
Вспомогательная блокировка достаточна для взаимодействующих программ, разделяющих индивидуальный файл, когда не предполагается использование этого файла ни одним другим приложением. Обязательная блокировка подходит в ситуации, когда избежание конфликта в использовании файла является критическим, как в коммерческих системах баз данных.
POSIX стандартизует лишь вспомогательную блокировку. Обязательная блокировка доступна на GNU/Linux, а также в ряде коммерческих систем Unix, но детали варьируют. Далее в данном разделе мы рассмотрим детали для GNU/Linux.
14.2.2. Блокировка POSIX: fcntl()
lockf()Системный вызов fcntl()
fcntl() было описано в разделе 9.4.3 «Управление атрибутами файла: fcntl()».) Он объявлен следующим образом:#include
#include
int fcntl(int fd, int cmd); /* Not relevant for file locking */
int fcntl(int fd, int cmd, long arg); /* Not relevant for file locking */
int fcntl(int fd, int cmd, struct flock *lock);
Аргументы следующие:
fd
cmd
. Ниже они описаны более подробно.lock
struct flock, описывающую нужный блок.14.2.2.1. Описание блокировки
Прежде чем рассмотреть осуществление блокировки, давайте исследуем описание блокировки в операционной системе. Это делается при помощи структуры struct flock
struct lock содержит «по крайней мере» определенные члены. Это позволяет разработчикам предоставлять при желании дополнительные члены структуры. Из слегка отредактированной справочной страницы struct flock {
...
short l_type; /* Тип блокировки: F_RDLCK, F_WRLCK, F_UNLCK */
short l_whence; /* Как интерпретируется l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Начальное блокируемое смещение */
off_t l_len; /* Число блокируемых байтов;
0 означает от начала до конца файла */
pid_t l_pid; /* PID блокирующего процесса (только F_GETLK) */
...
};
Поле l_start
l_len является длиной блокируемого участка, т. е. общим числом блокируемых байтов. l_whence указывает место в файле, относительно которого отсчитывается l_start, значения те же, что и для аргумента whence функции lseek() (см раздел 4.5 «Произвольный доступ: перемещения внутри файла»), отсюда и название поля. Эта структура самодостаточна: смещение l_start и значение l_whence struct employee { /* что угодно */ }; /* Описание сотрудника */
struct flock lock; /* Структура блока */
...
/* Заблокировать структуру для шестого сотрудника */
lock.l_whence = SEEK_SET; /* Абсолютное положение */
lock.l_start = 5 * sizeof(struct employee); /* Начало 6-й структуры */