Читаем Linux API. Исчерпывающее руководство полностью

Обычно вызов fcntl() применяется для блокировки байтов в диапазоне, который соответствует границам записи внутри файла, определенным на уровне приложения; отсюда и термин блокировка записей. Термины диапазон байтов, участок файла, сегмент файла применяются не так часто, но более точно описывают этот вид блокировки файлов (это единственный способ, описанный в оригинальной спецификации POSIX.1 и стандарте SUSv3, в связи с чем его иногда называют POSIX-блокировкой).

Стандарт SUSv3 требует, чтобы блокировка записей поддерживалась для обычных файлов, и допускает ее поддержку другими файловыми объектами. Как правило, эту блокировку имеет смысл применять только к обычным файлам (поскольку в случае с другими файловыми объектами понятие диапазона байтов теряет свое первоначальное значение), но в Linux это можно делать для любого файлового дескриптора.

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

Рис. 51.2.Синхронизация доступа к одному и тому же участку файла с помощью блокировки записей

В целом создание или удаление файловой блокировки с применением вызова fcntl() выглядит следующим образом:

struct flock flockstr;

/* Инициализируем поля 'flockstr', чтобы описать блокировку,

которую нужно установить или удалить */

fcntl(fd, cmd, &flockstr); /* Устанавливаем блокировку, описанную в 'fl' */

Аргумент fd представляет собой открытый дескриптор, ссылающийся на файл, который мы хотим заблокировать.

Прежде чем перейти к аргументу cmd, сначала познакомимся со структурой flock.

51.3.1. Структура flock

Структура flock описывает блокировку, которую нужно установить или снять. Она имеет следующее определение:

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; /* Процесс, не дающий нам установить

блокировку (только для F_GETLK) */

};

Поле l_type обозначает тип блокировки, которую мы хотим установить. Оно может принимать одно из значение, перечисленных в табл. 51.3.

С точки зрения семантики блокировки, предназначенные для чтения (F_RDLCK) и записи (F_WRLCK), соответствуют разделяемым и эксклюзивным блокировкам, устанавливаемым вызовом flock(), и подчиняются тем же правилам совместимости (см. табл. 51.2). Блокировку F_RDLCK, относящуюся к определенному участку файла, может удерживать любое количество процессов, но только один процесс может владеть блокировкой F_WRLCK (которая к тому же исключает блокировки любых типов, принадлежащих другим процессам). Использование значения F_UNLCK для аргумента l_type аналогично операции LOCK_UN для вызова flock().

Таблица 51.3. Типы блокировок, создаваемые вызовом fcntl()

Тип блокировки — Описание

F_RDLCK — Устанавливает блокировку для чтения

F_WRLCK — Устанавливает блокировку для записи

F_UNLCK — Удаляет существующую блокировку

Для установки блокировки F_RDLCK файл должен быть открыт для чтения. Аналогично F_WRLCK требует, чтобы файл был открыт для записи. Для размещения блокировок обоих видов файл следует открывать в режиме чтения-записи (O_RDWR). Попытка установить блокировку, несовместимую с режимом доступа к файлу, приведет к ошибке EBADF.

Поля l_whence, l_start и l_len в совокупности определяют диапазон байтов, которые нужно заблокировать. Первые два из них являются аналогами аргументов whence и offset для вызова lseek() (см. раздел 4.7). Поле l_start обозначает сдвиг внутри файла, вычисляемый относительно:

• начала файла, если аргумент l_whence равен SEEK_SET;

• текущего сдвига в файле, если аргумент l_whence равен SEEK_CUR;

• конца файла, если аргумент l_whence равен SEEK_END.

В двух последних случаях аргумент l_start может иметь отрицательное значение, если итоговая позиция находится не перед началом файла (байтом 0).

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

Начиная с версии 2.4.21 ядро Linux позволяет передавать аргументу l_len отрицательные значения. Это значит, что заблокировать нужно l_len байт, размещенных до позиции, заданной с помощью l_whence и l_start (то есть байты в диапазоне от (l_start — abs(l_len)) до (l_start — 1)). Такая возможность не является обязательной, но допускается стандартом SUSv3. Она также поддерживается в некоторых других реализациях UNIX.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных

Все жанры