13.3.4. Аренда файла

13.3.4. Аренда файла

И рекомендательное, и обязательное блокирование предназначены для предотвращения доступа процесса к файлу или его части, которая используется другим процессом. Когда блокировка установлена, процесс, которому необходим доступ к файлу, должен подождать завершения процесса, владеющего блокировкой. Эта структура подходит для большинства применений, но иногда программа использует файл до тех пор, пока он не понадобится другой программе, и желает получить при необходимости эксклюзивный доступ к файлу. Для этого Linux предлагает механизм аренды файлов (в других системах это называется периодическими блокировками (oplocks))[93].

Взятие файла в аренду позволяет процессу получать уведомления (через сигнал) о доступе к файлу со стороны другого процесса. Существуют два типа аренды: аренда чтения и аренда записи. Аренда чтения вызывает передачу сигнала при открытии файла для записи, открытии с указанием O_TRUNC или вызове truncate(). Аренда записи также посылает сигнал при открытии файла для чтения[94]22. Аренды файлов работают только для модификаций, внесенных в файл той же системой, которая владеет арендой. Если файл локальный (не файл, доступ к которому возможен через сеть), любой подходящий доступ к файлу инициирует сигнал. Если доступ к файлу возможен через сеть, передачу сигнала вызывают только процессы на одной машине с процессо-арендатором; доступ с любой другой машины удается в случае отсутствия аренды.

Системный вызов fcntl() используется для создания, реализации и запроса аренды файлов. Аренды можно размещать только на обычных файлах (для каналов и каталогов это невозможно), кроме того, аренды записи предоставляются только владельцу файла. Первый аргумент fcntl() — это интересующий для слежения файловый дескриптор, а второй аргумент, command, определяет, какую операцию следует выполнить.

F_SETLEASE

Аренда создается или освобождается в зависимости от значения последнего параметра, передаваемого в fcntl(); F_RDLCK создает аренду чтения, F_WRLCK — аренду записи, a F_UNLCK освобождает любую аренду, которая может существовать. Если запрашивается новая аренда, она заменяет любую существующую аренду. В случае ошибки возвращается отрицательное число; ноль или положительное число свидетельствуют об успехе операции[95].

F_GETLEASE

Возвращается тип аренды, существующей в настоящий момент для файла (F_RDLCK, F_WRLCK или F_UNLCK).

Когда в арендованном файле происходит одно из контролируемых событий, ядро передает сигнал удерживающему аренду процессу. По умолчанию передается SIGIO, но процесс может выбрать, какой сигнал передавать этому файлу, с помощью вызова fcntl(), в котором второй параметр установлен в F_SETSIG, а последний — в сигнал, который должен использоваться вместо SIGIO.

Использование F_SETSIG дает один значительный эффект. По умолчанию siginfo_t не передается обработчику при доставке SIGIO. Если используется F_SETSIG, даже когда сигналом, передаваемым в ядро, является SIGIO, a SA_SIGINFO был установлен при регистрации обработчика сигнала, файловый дескриптор, аренда которого инициировала событие, передается в обработчик сигналов одновременно с элементом siginfo_t по имени si_fd. Это позволяет применять отдельный сигнал к аренде множества файлов, в то время как si_fd сообщает сигналу, какому файлу необходимо уделить внимание[96].

Единственные два системных вызова, которые могут инициировать передачу сигнала для арендуемого файла — это open() и truncate(). Когда они вызываются процессом для арендуемого файла, они блокируются[97], и процессу-владельцу передается сигнал, open() или truncate() завершаются после удаления аренды с файла (или его закрытия процессом-владельцем, что вызывает удаление аренды). Если процесс, удерживающий аренду, не отменяет снятие в течение времени, указанного в файле /proc/sys/fs/lease-break-time, ядро прерывает аренду и позволяет завершиться запускающему системному вызову.

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

 1: /* leases.с */

 2:

 3: #define GNU_SOURCE

 4:

 5: #include <fcntl.h>

 6: #include <signal.h>

 7: #include <stdio.h>

 8: #include <string.h>

 9: #include <unistd.h>

10:

11: const char ** fileNames;

12: int numFiles;

13:

14: void handler (int sig, siginfo_t * siginfo, void * context) {

15:  /* Когда аренда истекает, вывести сообщение и закрыть файл.

16:     Предполагается, что первый открываемый файл получит файловый

17:     дескриптор 3, следующий - 4 и так далее. */

18:

19:  write(1, "освобождение", 10);

20:  write(1, fileNames[siginfo->si_fd - 3],

21:  strlen(fileNames[siginfo->si_fd - 3]));

22:  write(1, " ", 1);

23:  fcntl(siginfo->si_fd, F_SETLEASE, F_UNLCK);

24:  close(siginfo->si_fd);

25:  numFiles--;

26: }

27:

28: int main(int argc, const char ** argv) {

29:  int fd;

30:  const char ** file;

31:  struct sigaction act;

32:

33:  if (argc < 2) {

34:   fprintf(stderr, "использование: %s <filename>+ ", argv[0]);

35:   return 1;

36:  }

37:

38:  /* Зарегистрировать обработчик сигналов. Указав SA_SIGINFO, предоставить

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

40:     истекшую аренду. */

41:  act.sa_sigaction = handler;

42:  act.sa_flags = SA_SIGINFO;

43:  sigemptyset(&act.sa_mask);

44:  sigaction(SIGRTMIN, &act, NULL);

45:

46:  /* Сохранить список имен файлов в глобальной переменной, чтобы

47:     обработчик сигналов мог иметь доступ к нему. */

48:  fileNames = argv + 1;

49:  numFiles = argc - 1;

50:

51:  /* Открыть файлы, установить используемые сигнал

52:     и создать аренду */

53:  for (file = fileNames; *file; file++) {

54:   if ((fd = open(* file, O_RDONLY)) < 0) {

55:    perror("open");

56:    return 1;

57:   }

58:

59:   /* Для правильного заполнения необходимо использовать F_SETSIG

60:      для структуры siginfo */

61:   if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0) {

62:    perror("F_SETSIG");

63:    return 1;

64:   }

65:

66:   if (fcntl(fd, F_SETLEASE, F_WRLCK) < 0) {

67:    perror("F_SETLEASE");

68:    return 1;

69:   }

70:  }

71:

72:  /* Пока файлы остаются открытыми, ожидать поступления сигналов. */

73:  while (numFiles)

74:   pause();

75:

76:  return 0;

77: }

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.7 СОЗДАНИЕ ФАЙЛА

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

5.7 СОЗДАНИЕ ФАЙЛА Системная функция open дает процессу доступ к существующему файлу, а системная функция creat создает в системе новый файл. Синтаксис вызова системной функции creat:fd = creat(pathname, modes);где переменные pathname, modes и fd имеют тот же смысл, что и в системной функции open. Если


Элементы WS-файла

Из книги Windows Script Host для Windows 2000/XP автора Попов Андрей Владимирович

Элементы WS-файла В WS-файл можно вставлять комментарии независимо от разметки XML. Сделать это можно двумя способами: с помощью элемента <!-- --> или элемента <comment>. Например:<!-- Первый комментарий -->или<comment>Второй


Элементы WSC-файла

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Элементы WSC-файла В WSC-файлы можно вставлять комментарии двумя разными способами: с помощью элемента <!-- --> или элемента <comment>. Например:<!-- Первый комментарий -->или<comment>Второй


Установка размера файла, инициализация файла и разреженные файлы

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

Установка размера файла, инициализация файла и разреженные файлы Функция SetEndOfFile позволяет переустановить размер файла, используя текущее значение указателя файла для определения его размера. Возможно как расширение, так и усечение файла. В случае расширения файла


11.9.2 Аренда адресов

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

11.9.2 Аренда адресов Процесс выделения адресов предполагает запрос клиентом IP-адреса на определенный период времени (возможно, что и навсегда). Сервер предоставляет клиенту адрес в аренду, указывая период использования данного адреса. Клиент должен периодически


10.1.2. Обновление файла

Из книги Справочник по PHP автора

10.1.2. Обновление файла Чтобы открыть файл для чтения и записи, достаточно добавить знак плюс (+) в строку указания режима (см. раздел 10.1.1):f1 = File.new("file1", "r+")# Чтение/запись, от начала файла.f2 = File.new("file2", "w+")# Чтение/запись; усечь существующий файл или создать новый.f3 = File.new("file3", "а+")#


Закрытие файла

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

Закрытие файла fcloseЗакрывает файл, открытый предварительно функцией fopen().Синтаксис:int fclose(int $fp)Возвращает false, если файл закрыть не удалось (например, что-то с ним случилось или же разорвалась связь с удаленным хостом). В противном случае возвращает значение "истина".Всегда


11.1. Режим файла

Из книги C++. Сборник рецептов автора Диггинс Кристофер

11.1. Режим файла Каждый файл в системе имеет как тип (вроде неименованного канала или символьного устройства), так и набор прав доступа, определяющих, какие процессы могут иметь доступ к файлу. Тип файла и права доступа комбинируются в 16-битное значение (тип short в С),


10.7. Копирование файла

Из книги Программирование КПК и смартфонов на .NET Compact Framework автора Климов Александр П.

10.7. Копирование файла ПроблемаТребуется скопировать файл, причем так, чтобы эта операция была переносимой, т.е. без использования зависящего от ОС программного интерфейса.РешениеИспользуйте файловые потоки С++, определенные в <fstream>, для копирования одного потока в


Создание cab-файла

Из книги Linux глазами хакера автора Флёнов Михаил Евгеньевич

Создание cab-файла Прежде чем установочный пакет попадет в руки пользователя, нужно хорошенько поработать над его созданием. Устройства под управлением Windows Mobile не могут напрямую работать с файлами .msi. Вместо этого используются кабинетные файлы с расширением .cab. Таким


Код файла заголовков

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Код файла заголовков #define NET_OPER "/net/904-3"#define NET_REG "/net/Bed-Test"// Максимальная длина обычного стандартного сообщения.#define MESSIZE_MAX 100// Максимальная длина инвентаризационного имени процесса#define PROC_NAME_MAX 100struct IdLabel_t { // Структура, содержащая, int id; // -.инвентаризационную метку


4.1.2. Владелец файла

Из книги Операционная система UNIX автора Робачевский Андрей М.

4.1.2. Владелец файла Для изменения владельца файла существует команда chown:chown имя файлЧерез параметр имя определяется пользователь, которому нужно передать права на указанный файл. Например, давайте сделаем владельцем файла test администратора root. Для этого нужно выполнить


Б.1.1. Открытие файла

Из книги автора

Б.1.1. Открытие файла Чтобы открыть файл и получить дескриптор для работы с ним, необходимо вызвать функцию open(). В качестве аргументов она принимает строку с путевым именем файла и флаги, определяющие способ открытия. С помощью функции open() можно также создать новый файл.


Б.1.2. Закрытие файла

Из книги автора

Б.1.2. Закрытие файла По окончании работы с файлом его следует закрыть с помощью функции close(). В ряде случаев, например в программе, показанной в листинге Б.1, нет необходимости вызывать данную функцию явно, так как ОС Linux автоматически закрывает все открытые файлы по


Метаданные файла

Из книги автора

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