9.3. Блокирование записей с помощью fcntl по стандарту Posix

9.3. Блокирование записей с помощью fcntl по стандарту Posix

Согласно стандарту Posix, интерфейсом для блокировки записей является функция fcntl:

#include <fcntl.h>

int fcntl(int fd, int cmd,… /* struct flock *arg */);

/* Возвращает –1 в случае ошибки: результат, возвращаемый в случае успешного завершения, зависит от аргумента cmd */

Для блокировки записей используются три различных значения аргумента cmd. Эти три значения требуют, чтобы третий аргумент, arg, являлся указателем на структуру flock:

struct flock {

 short l_type;   /* F_RDLCK, F_WRLCK, F_UNLCK */

 short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */

 off_t l_start;  /* относительный сдвиг в байтах */

 off_t l_len;    /* количество байтов; 0 означает до конца файла */

 pid_t l_pid;    /* PID, возвращаемый F_GETLK */

};

Вот три возможные команды (значения аргумента cmd ):

? F_SETLK — получение блокировки (l_type имеет значение либо F_RDLCK, либо F_WRLCK) или сброс блокировки (l_type имеет значение F_UNLCK), свойства которой определяются структурой flock, на которую указывает arg. Если процесс не может получить блокировку, происходит немедленный возврат с ошибкой EACCESS или EAGAIN.

? F_SETLKW — эта команда идентична предыдущей. Однако при невозможности блокирования ресурса процесс приостанавливается, до тех пор пока блокировка не сможет быть получена (W в конце команды означает «wait»).

? F_GETLK — проверка состояния блокировки, на которую указывает arg. Если в данный момент блокировка не установлена, поле l_type структуры flock, на которую указывает arg, будет иметь значение F_UNLCK. В противном случае в структуре flock, на которую указывает arg, возвращается информация об установленной блокировке, включая идентификатор процесса, заблокировавшего ресурс. 

Обратите внимание, что последовательный вызов F_GETLK и F_SETLK не является атомарной операцией. Если мы вызвали F_GETLK и она вернула значение F_UNLCK в поле l_type, это не означает, что немедленный вызов F_SETLK будет успешным. Между этими двумя вызовами другой процесс мог уже заблокировать ресурс.

Причина, по которой была введена команда F_GETLK, — необходимость получения информации о блокировке в том случае, когда F_SETLK возвращает ошибку. Мы можем узнать, кто и каким образом заблокировал ресурс (на чтение или на запись). Но и в этом случае мы должны быть готовы к тому, что F_GETLK вернет результат F_UNLCK, поскольку между двумя вызовами другой процесс мог освободить ресурс.

Структура flock описывает тип блокировки (чтение или запись) и блокируемый диапазон. Как и в 1 seek, начальный сдвиг представляет собой сдвиг относительно начала файла, текущего положения или конца файла, и интерпретируется в зависимости от значения поля l_whence (SEEK_SET, SEEK_CUR, SEEK_END).

Поле l_len указывает длину блокируемого диапазона. Значение 0 соответствует блокированию от l_start до конца файла. Существуют, таким образом, два способа заблокировать файл целиком:

1. Указать l_whence = SEEK_SET, l_start = 0 и l_len = 0.

2. Перейти к началу файла с помощью lseek, затем указать l_whence = SEEK_CUR, l_start = 0 и l_len = 0.

Чаще всего используется первый метод, поскольку он предусматривает единственный вызов (fcntl — см. также упражнение 9.10).

Блокировка может быть установлена либо на чтение, либо на запись, и для конкретного байта файла может быть задан только один тип блокировки. Более того, на конкретный байт может быть установлено несколько блокировок на чтение, но только одна блокировка на запись. Это соответствует тому, что говорилось о блокировках чтения-записи в предыдущей главе. Естественно, при попытке установить блокировку на чтение для файла, открытого только на запись, будет возвращена ошибка.

Все блокировки, установленные конкретным процессом, снимаются при закрытии дескриптора файла этим процессом и при завершении его работы. Блокировки не наследуются дочерним процессом при вызове fork.

ПРИМЕЧАНИЕ

Снятие блокировок при завершении процесса обеспечивается только для блокировок записей fcntl и (в качестве дополнительной возможности) для семафоров System V. Для других средств синхронизации (взаимных исключений, условных переменных, блокировок чтения-записи и семафоров Posix) автоматическое снятие при завершении процесса не предусматривается. Об этом мы говорили в конце раздела 7.7. 

Блокировка записей не должна использоваться со стандартной библиотекой ввода-вывода, поскольку функции из этой библиотеки осуществляют внутреннюю буферизацию. С заблокированными файлами следует использовать функции read и write, чтобы не возникало неожиданных проблем. 

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Практическая работа 51. Отбор записей из списка с помощью фильтра

Из книги Компьютер на 100. Начинаем с Windows Vista автора Зозуля Юрий

Практическая работа 51. Отбор записей из списка с помощью фильтра Задание 1. Отобрать в прайс-листе (см. рис. 6.65) только товары, которые имеются на складе.Последовательность выполнения1. Откройте список товаров, который сохранен под именем Товары на складе (см. рис. 6.65).2. В


Отбор записей с помощью предложения SELECT

Из книги Обработка баз данных на Visual Basic®.NET автора Мак-Манус Джеффри П

Отбор записей с помощью предложения SELECT Предложение SELECT является основой каждого запроса, предназначенного для выборки данных. Оно указывает процессору баз данных, какие поля требуется возвратить. Общая форма предложения SELECT имеет следующий вид:SELECT *А его содержание


Указание источника записей с помощью предложения FROM

Из книги Word 2007.Популярный самоучитель автора Краинский И

Указание источника записей с помощью предложения FROM Предложение FROM указывает на источник записей, из которого запрос извлекает записи. Этим источником может быть как таблица, так и другой хранимый запрос. У вас также есть возможность отбора записей из нескольких таблиц,


Отображение первых или последних записей диапазона с помощью предложения ТОР

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Отображение первых или последних записей диапазона с помощью предложения ТОР Ключевое слово ТОР используется для отображения некоторого количества начальных или конечных записей из большого результирующего набора. Для ограничения числа записей в результирующем


8.2. Публикация записей в блоге с помощью Word

Из книги C++. Сборник рецептов автора Диггинс Кристофер

8.2. Публикация записей в блоге с помощью Word Нововведением Word 2007 является возможность опубликовывать записи в блоги непосредственно из окна программы. Это очень удобно, поскольку Word имеет гораздо больше возможностей по набору и форматированию текста, чем текстовые


9.2. Блокирование записей и файлов

Из книги Linux программирование в примерах автора Роббинс Арнольд

9.2. Блокирование записей и файлов Ядро Unix никак не интерпретирует содержимое файла, оставляя всю обработку записей приложениям, работающим с этим файлом. Тем не менее для описания предоставляемых возможностей используется термин «блокировка записей». В


Блокировка записей fcntl

Из книги Операционная система UNIX автора Робачевский Андрей М.

Блокировка записей fcntl Последняя пpoгрaммa использует fcntl для синхронизации. Функция main приведена в листинге А.30. Эта программа будет выполняться успешно только в том случае, если количество потоков равно 1, поскольку блокировка fcntl предназначена для использования между


1.24. Включение строгого соответствия стандарту C++

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

1.24. Включение строгого соответствия стандарту C++ ПроблемаВы хотите, чтобы компилятор принимал только программы, которые соответствуют стандарту языка С++.РешениеОпции командной строки для указания строгого соответствия стандарту C++ приведены в табл. 1.37. Инструкции для


Удаление повторяющихся записей с помощью запросов

Из книги автора

Удаление повторяющихся записей с помощью запросов Существует еще одна полезная область применения запросов – удаление полностью или частично одинаковых записей. Если взять в качестве примера учебную базу Отдел продаж , то очевидно, что при корректной работе с таблицей


9.4.3. Управление атрибутами файла: fcntl()

Из книги автора

9.4.3. Управление атрибутами файла: fcntl() Системный вызов fcntl() («управление файлом») предоставляет контроль над различными атрибутами либо самого дескриптора файла, либо лежащего в его основе открытого файла. Справочная страница GNU/Linux fcntl(2) описывает это таким способом:#include


9.4.3.5. Сводка fcntl()

Из книги автора

9.4.3.5. Сводка fcntl() Сводка для системного вызова fcntl() приведена в табл. 9.5.Таблица 9.5. Сводка fcntl() Значение cmd Значение arg Возвращает F_DUPFD Наименьший новый дескриптор Дублирует аргумент fd F_GETFD Получает флаги дескриптора файла (close-on-exec) F_SETFD Новое значение


14.2.2. Блокировка POSIX: fcntl() и lockf()

Из книги автора

14.2.2. Блокировка POSIX: fcntl() и lockf() Системный вызов fcntl() (file control — управление файлом) используется для блокировки файла. (Другое использование fcntl() было описано в разделе 9.4.3 «Управление атрибутами файла: fcntl()».) Он объявлен следующим образом:#include <unistd.h> /* POSIX */#include <fcntl.h>int


Функция fcntl(2)

Из книги автора

Функция fcntl(2) После открытия файла и получения ссылки на него в виде файлового дескриптора процесс может производить различные файловые операции. Функция fcntl(2) позволяет процессу выполнить ряд действий с файлом, используя его дескриптор, передаваемый в качестве первого


7.11. Функция fcntl

Из книги автора

7.11. Функция fcntl Сокращение fcntl означает «управление файлами» (file control). Эта функция выполняет различные операции управления дескрипторами. Перед описанием этой функции и ее влияния на сокет нам нужно составить некоторое более общее представление о ее возможностях. В табл.


Блокирование и разблокирование сигнала с помощью функции pselect

Из книги автора

Блокирование и разблокирование сигнала с помощью функции pselect Одним из корректных решений будет использование функции pselect (см. раздел 6.9), как показано в листинге 20.3.Листинг 20.3. Блокирование и разблокирование сигналов с помощью функции pselect//bcast/dgclibcast4.с 1 #include "unp.h" 2 static