Читаем 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 / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных
C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

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