Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

8.2.2. Блокировка записей при помощи вызова fcntl

О системном вызове управления файловым вводом/выводом fcntl уже упоминалось ранее. В дополнение к привычным функциям вызов fcntl может также использоваться для выполнения блокировки записей. Он предлагает два типа блокировки:

  • блокировка чтения (read locks) – просто предотвращает установку другими процессами блокировки записи при помощи вызова fcntl. Несколько процессов могут одновременно выполнять блокировку чтения для одного и того же участка файла. Блокировка чтения может быть полезной, если, например, требуется предотвратить обновление данных, не скрывая их от просмотра другими пользователями;

  • блокировка записи (write locks) – предотвращает установку другими процессами блокировку чтения или записи для файла. Другими словами, для заданного участка файла может существовать только одна блокировка записи одновременно. Блокировка записи может использоваться, например, для скрытия участков файла от просмотра при выполнении обновления.

Следует напомнить, что в соответствии со спецификацией XSI блокировка вызовом fcntl является всего лишь рекомендательной. Поэтому процессам необходимо явно согласовывать свои действия, чтобы блокировка вызовом fcntl была действенной (процессы не должны производить операции ввода/вывода без предварительного блокирования соответствующей области).

Для блокировки записей вызов fcntl используется следующим образом:

Описание

uses linux, stdio;

Procedure Fcntl(filedes:longint; Cmd:longint; ldata: pflockrec);

Как обычно, аргумент filedes должен быть допустимым дескриптором открытого файла. Для блокировки чтения дескриптор filedes должен быть открыт при помощи флагов Open_RDONLY или Open_RDWR, поэтому в качестве него не подойдет дескриптор, возвращаемый вызовом fdcreat. Для блокировки записи дескриптор filedes должен быть открыт при помощи флагов Open_WRONLY или Open_RDWR.

Как уже упоминалось, параметр вызова cmd определяет выполняемое действие, кодируемое одним из значений, определенных в файле linux. Следуют три команды относятся к блокировке записей:

F_GETLK

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

F_SETLK

Попытаться применить блокировку к файлу и немедленно возвратить управление, если это невозможно. Используется также для удаления активной блокировки

F_SETLKW

Попытаться применить блокировку к файлу и приостановить работу, если блокировка уже наложена другим процессом. Ожидание процесса внутри вызова fcntl можно прервать при помощи сигнала

ldata содержит описание блокировки. Структура flockrec определена в файле stdio и включает следующие элементы:

flockrec=record

l_type:word; (*Описывает тип блокировки: F_RDLCK, F_WRLCK, F_UNLCK. *)

l_whence:word; (* Тип смещения, как и в вызове lseek *)

l_start:longint; (* Смещение в байтах *)

l_len:longint; (*Размер сегмента данных; 0 означает до конца файла *)

l_pid:longint; (*Устанавливается командой F_GETLK *)

end;

Три элемента, l_whence, l_start и l_len, определяют участок файла, который будет заблокирован, проверен или разблокирован. Переменная l_whence идентична третьему аргументу вызова lseek. Она принимает одно из трех значений: SEEK_SET, SEEK_CUR или SEEK_END, обозначая, что смещение должно вычисляться от начала файла, от текущей позиции указателя чтения-записи или конца файла. Элемент l_start устанавливает начальное положение участка файла по отношению к точке, заданной элементом l_whence. Элемент l_len является длиной участка в байтах; нулевое значение обозначает участок с заданной начальной позиции до максимально возможного смещения. На рис. 8.1. показано, как это работает для случая, если значение поля l_whence равно SEEK_CUR. Структура tsemid_ds определена в файле linux.

Указатель файла

|

|

|

|

Блокируемый участок

/

\

a

b

c

d

e

f

g

h

i

j

k

l

m

n

o

p

q

r

s

t

u

v

w

|

|

|

l_start

l_len

←–––––––→

←–––––––→

l_whence=

SEEK_CUR

Рис. 8.1. Параметры блокировки

Тип l_type определяет тип блокировки. Он может принимать одно из трех значений, определенных в файле stdio:

F_RDLCK Выполняется блокировка чтения

F_WRLCK Выполняется блокировка записи

F_UNLCK Снимается блокировка заданного участка

Поле l_pid существенно только при выборе команды F_GETLK в вызове fcntl. Если существует блокировка, препятствующая установке блокировки, описанной полями структуры ldata, то значение поля l_pid будет равно значению идентификатора процесса, установившего ее. Другие элементы структуры также будут переустановлены системой. Они будут содержать параметры блокировки, наложенной другим процессом.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal