Linux программирование в примерах
Шрифт:
#include <unistd.h> /* POSIX */
#include <fcntl.h>
int fcntl(int fd, int cmd); /* Not relevant for file locking */
int fcntl(int fd, int cmd, long arg); /* Not relevant for file locking */
int fcntl(int fd, int cmd, struct flock *lock);
Аргументы следующие:
fd
Дескриптор файла для открытого файла. cmd
Одна или более именованных констант, определенных
<fcntl.h>
. Ниже они описаны более подробно. lock
Указатель на struct flock
, описывающую нужный блок. 14.2.2.1. Описание блокировки
Прежде чем рассмотреть осуществление блокировки, давайте исследуем описание блокировки в операционной системе. Это делается при помощи структуры
struct flock
, которая описывает диапазон блокируемых байтов и вид нужной блокировки. Стандарт POSIX утверждает, что struct lock
содержит «по крайней мере» определенные члены. Это позволяет разработчикам предоставлять при желании дополнительные члены структуры. Из слегка отредактированной справочной страницы fcntl(3):
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; /* PID блокирующего процесса (только F_GETLK) */
...
};
Поле
l_start
является смешением начального байта блокируемого участка. l_len
является длиной блокируемого участка, т. е. общим числом блокируемых байтов. l_whence
указывает место в файле, относительно которого отсчитывается l_start
, значения те же, что и для аргумента whence
функции lseek
(см раздел 4.5 «Произвольный доступ: перемещения внутри файла»), отсюда и название поля. Эта структура самодостаточна: смещение l_start
и значение l_whence
не связаны с текущим файловым указателем для чтения или записи. Пример кода мог бы выглядеть таким образом:
struct employee { /* что угодно */ }; /* Описание сотрудника */
struct flock lock; /* Структура блока */
...
/* Заблокировать структуру для шестого сотрудника */
lock.l_whence = SEEK_SET; /* Абсолютное положение */
lock.l_start = 5 * sizeof(struct employee); /* Начало 6-й структуры */
lock.l_len = sizeof(struct employee); /* Блокировать одну
запись */
Используя
SEEK_CUR
или SEEK_END
, вы можете заблокировать участки, начиная от текущего смещения в файле или относительно конца файла соответственно. Для этих двух случаев l_start
может быть отрицательным, пока абсолютное начало не меньше нуля. Таким образом, чтобы заблокировать последнюю запись в файле:
/* Заблокировать запись последнего сотрудника */
lock.l_whence = SEEK_END; /* Относительно EOF */
lock.l_start = -1 * sizeof (struct employee);
/* Начало последней структуры */
lock.l_len = sizeof(struct employee); /* Заблокировать одну запись */
Установка
l_len
в 0 является особым случаем. Он означает блокировку файла от начального положения, указанного с помощью l_start
и l_whence
, и до конца файла. Сюда входят также любые области за концом файла. (Другими словами, если заблокированный файл увеличивается в размере, область блокировки расширяется таким образом, чтобы продолжать охватывать весь файл.) Таким образом, блокирование всего файла является вырожденным случаем блокирования одной записи:
lock.l_whence = SEEK_SET; /* Абсолютное положение */
lock.l_start = 0; /* Начало файла */
lock.l_len = 0; /* До конца файла */
Справочная страница fnctl(3) имеет примечание:
POSIX 1003.1-2001 допускает отрицательные значения
l_len
. (И если это так, описываемый блоком интервал охватывает байты с l_start + l_len
вплоть до l_start - 1
включительно.) Однако, в этой ситуации системный вызов Linux для современных ядер возвращает EINVAL
. (Мы заметили, что справочная страница относится к версиям ядер 2.4.x; стоит проверить текущую справочную страницу, если ваша система новее.)
Теперь, когда мы знаем, как описать где блокируется файл, мы можем описать тип блокировки с помощью
l_type
. Возможные значения следующие: F_RDLCK
Блокировка чтения. Для применения блокировки чтения файл должен быть открыт для чтения. F_WRLCK
Блокировка записи. Для применения блокировки записи файл должен быть открыт для записи. F_UNLCK
Освобождение предыдущей блокировки. Таким образом, полная спецификация блокировки включает установку в структуре
struct flock
значений четырех полей: трех для указания блокируемой области и четвертого для описания нужного типа блока. Значение
F_UNLCK
для l_type
снимает блокировку. В общем, это простейший способ снять те самые блоки, которые были установлены ранее, но можно «расщепить» блок, освободив диапазон байтов в середине ранее установленного более крупного блока. Например:
Поделиться:
Популярные книги
Оживший камень
1. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мой муж – чудовище! Изгнанная жена дракона
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Идеальный мир для Лекаря 23
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Потомок бога 3
3. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Барон не играет по правилам
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар темного лорда VI
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Я еще не князь. Книга XIV
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 23
23. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Камень. Книга 4
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Убивать чтобы жить 7
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Старый, но крепкий 4
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Вернувшийся: Корпорация. Том III
3. Вернувшийся
Фантастика:
космическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Первый среди равных. Книга VI
6. Первый среди Равных
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство 9
9. Ваше Сиятельство
Фантастика:
боевая фантастика
попаданцы
стимпанк
аниме
фэнтези
5.00