Установка блокировки при помощи вызова fcntl
Следующий пример показывает, как можно использовать вызов fcntl для установления блокировки записи.
uses linux,stdio;
.
.
.
var
my_lock:flockrec;
my_lock.l_type := F_WRLCK;
my_lock.l_whence := SEEK_CUR;
my_lock.l_start := 0;
my_lock.l_len := 512;
fcntl (fd, F_SETLKW, longint(@my_lock));
При этом будут заблокированы 512 байт, начиная с текущего положения указателя чтения-записи. Заблокированный участок теперь считается «зарезервированным» для исключительного использования процессом. Информация о блокировке помещается в свободную ячейку системной таблицы блокировок.
Если весь участок файла или какая-то его часть уже были заблокированы другим процессом, то вызывающий процесс будет приостановлен до тех пор, пока не будет доступен весь участок. Приостановка работы процесса может быть прервана при помощи сигнала; в частности, для задания времени ожидания может быть использован вызов alarm. Если ожидание не будет прервано, и, в конце концов, участок файла освободится, то процесс заблокирует его. Если происходит ошибка, например, если вызову fcntl передается неверный дескриптор файла или переполнится системная таблица блокировок, то будет возвращено значение -1.
Следующий пример – программа lockit открывает файл с именем locktest (который должен существовать) и блокирует его первые десять байт при помощи вызова fcntl. Затем она порождает дочерний процесс, пытающийся заблокировать первые пять байт файла; родительский процесс в это время делает паузу на пять секунд, а затем завершает работу. В этот момент система автоматически снимает блокировку, установленную родительским процессом.
(* Программа lockit - блокировка при помощи вызова fcntl *)
uses linux,stdio;
var
fd:integer;
my_lock:flockrec;
begin
(* Установка параметров блокировки записи *)
my_lock.l_type := F_WRLCK;
my_lock.l_whence := SEEK_SET;
my_lock.l_start := 0;
my_lock.l_len := 10;
(* Открыть файл *)
fd := fdopen ('locktest', Open_RDWR);
(* Заблокировать первые десять байт *)