Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

ПРИМЕЧАНИЕ

Потомки BSD поддерживают лишь блокировку файла целиком с помощью функции flock. Возможность заблокировать диапазон байтов не предусматривается. 

История

За долгие годы было разработано множество методов блокировки файлов и записей. Древние программы вроде UUCP и демонов печати играли на реализации файловой системы (три из них описаны в разделе 9.8). Они работали достаточно медленно и не подходили для баз данных, которые стали появляться в начале 80-х.

Первый раз возможность блокировать файлы и записи появилась в Version 7, куда она была добавлена Джоном Бассом John Bass) в 1980 году в виде нового системного вызова locking. Это блокирование было обязательным (mandatory locking); его унаследовали многие версии System III и Xenix. (Разница между обязательным и рекомендательным блокированием и между блокированием записей и файлов описана далее в этой главе.)

Версия 4.2BSD предоставила возможность блокирования файлов (а не записей) функцией flock в 1983. В 1984 году стандарт /usr/group (один из предшественников Х/Open) определил функцию lockf, которая осуществляла только исключающую блокировку (на запись), но не совместную.

В 1984 году в System V Release 2 была добавлена возможность рекомендательной блокировки записей с помощью fcntl. Функция lockf в этой версии также имелась, но она осуществляла просто вызов fcntl. (Многие нынешние версии также реализуют lockf через вызов fcntl.) В 1986 году в версии System V Release 3 появилась обязательная блокировка записей с помощью fcntl. При этом использовался бит set-group-ID (установка идентификатора группы) — об этом методе рассказано в разделе 9.5.

В 1988 году стандарт Posix.1 включил в себя рекомендательную и обязательную блокировку файлов и записей с помощью функции fcntl, и это именно то, что является предметом обсуждения данной главы. Стандарт X/Open Portability Guide Issue 3 (XPG3, 1988) также указывает на необходимость осуществления блокировки записей через fcntl.

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, поскольку между двумя вызовами другой процесс мог освободить ресурс.

  • Читать дальше
  • 1
  • ...
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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