Вход/Регистрация
Основы программирования в Linux
вернуться

Мэтью Нейл

Шрифт:
Примечание

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

Блокировка участков файла

Создание файлов с блокировкой подходит для управления исключительным доступом к ресурсам, таким как последовательные порты или редко используемые файлы, но этот способ не годится для доступа к большим совместно используемым файлам. Предположим, что у вас есть большой файл, написанный одной программой и одновременно обновляемый многими программами. Такая ситуация может возникнуть, если программа записывает какие-то данные, получаемые непрерывно или в течение длительного периода, и обрабатывает их с помощью нескольких разных программ. Обрабатывающие программы не могут ждать, пока программа, записывающая данные, завершится — она работает постоянно, поэтому программам нужен какой-то способ кооперации для обеспечения одновременного доступа к одному и тому же файлу.

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

fcntl
или системного вызова
lockf
. Мы рассмотрим интерфейс
fcntl
, поскольку он наиболее часто применяется. Интерфейс
lockf
в основном аналогичен, и в ОС Linux он используется как альтернативный интерфейсу
fcntl
. Однако блокирующие механизмы
fcntl
и
lockf
не работают вместе: у них разные низкоуровневые реализации. Поэтому никогда не следует смешивать вызовы этих двух типов; выберите один или другой.

Вы встречали вызов fcntl в главе 3. У него следующее определение:

#include <fcntl.h>

int fcntl(int fildes, int command, ...);

Системный вызов

fcntl
оперирует открытыми дескрипторами файлов и, в зависимости от параметра
command
, может выполнять разные задачи. Для блокировки файлов интересны три приведенные далее возможные значения параметра command:

F_GETLK
;

F_SETLK
;

F_SETLKW
.

Когда вы используете эти варианты, третий аргумент в вызове должен быть указателем на структуру

struct flock
, поэтому на самом деле прототип вызова выглядит следующим образом:

int fcntl(int fildes, int command, struct flock *flock_structure);

Структура

flock
(он англ. file lock) зависит от конкретной реализации, но, как минимум, она будет содержать следующие элементы:

short l_type
;

short l_whence
;

off_t l_start
;

off_t l_len
;

pid_t l_pid
.

Элемент

l_type
принимает одно из нескольких значений (табл. 7.1), определенных в файле fcntl.h.

Таблица 7.1.

Значение Описание
F_RDLCK
Разделяемая или совместная блокировка (блокировка на чтение). У разных процессов может быть разделяемая блокировка одних и тех же (или перекрывающихся) участков файла. Если у какого-либо процесса есть разделяемая блокировка, ни один процесс не сможет установить исключительную блокировку этого участка. Для получения совместной блокировки файл должен быть открыт с правом на чтение или на чтение/запись
F_UNLCK
Разблокировать. Применяется для снятия блокировок
F_WRLCK
Исключительная блокировка (или блокировка на запись). Только один процесс может установить исключительную блокировку на любой конкретный участок файла. После того как процесс установил такую блокировку, никакой другой процесс не сможет установить блокировку любого типа на этот участок файла. Для установки исключительной блокировки файл должен быть открыт с правом на запись или на чтение/запись

Элементы

l_whence
,
l_start
и
l_len
определяют участок файла, непрерывную область в байтах. Элемент
l_whence
должен задаваться одним из следующих значений:
SEEK_SET
,
SEEK_CUR
,
SEEK_END
(из файла unistd.h). Они соответствуют началу, текущей позиции или концу файла соответственно. Элемент
l_whence
задает смещение для первого байта участка файла, определенного элементом
l_start
. Обычно оно задается константой
SEEK_SET
, поэтому
l_start
отсчитывается от начала файла. Параметр
l_len
содержит количество байтов в участке файла.

Параметр

l_pid
применяется для указания процесса, установившего блокировку; см. следующее далее описание значения
F_GETLK
параметра
command
.

Для каждого байта в файле может быть установлена блокировка только одного типа в каждый конкретный момент времени и может быть либо разделяемой блокировкой, либо исключительной или блокировка может отсутствовать. Для системного вызова

fcntl
существует совсем немного комбинаций значений команд и вариантов, поэтому рассмотрим их все по очереди.

  • Читать дальше
  • 1
  • ...
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: