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

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

Шрифт:

Пример: упрощение с помощью макросов

В листинге 9.3 установка и снятие блокировки занимали шесть строк кода. Мы должны выделить место под структуру, инициализировать ее и затем вызвать fcntl. Программы можно упростить, если определить следующие семь макросов, которые взяты из раздела 12.3 [21]:

#define read_lock(fd, offset, whence, len) \

 lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)

#define readw_lock(fd, offset, whence, len) \

 lock_reg(fd, F_SETLKW, F_RDlCK, offset, whence, len)

#define write_lock(fd, offset, whence, len) \

 lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)

#define writew_lock(fd, offset, whence, len) \

 lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)

#define un_lock(fd, offset, whence, len) \

 lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)

#define is_read_lockable(fd, offset, whence, len) \

 lock_test(fd, F_RDLCK, offset, whence, len)

#define is_write_lockable(fd, offset, whence, len) \

 lock_test(fd, F_WRLCK, offset, whence, len)

Эти макросы используют наши функции lock_reg и lock_test, текст которых приведен в листингах 9.4 и 9.5. С ними нам уже не нужно заботиться об инициализации структур и вызове функций. Первые три аргумента специально сделаны совпадающими с первыми тремя аргументами функции lseek.

Мы также определяем две функции-обертки, Lock_reg и Lock_test, завершающие свое выполнение с возвратом ошибки fcntl, и семь макросов с именами, начинающимися с заглавной буквы, чтобы эти функции вызывать.

С помощью новых макросов мы можем записать функции my_lock и my_unlock из листинга 9.3 как

#define my_lock(fd) (Writew_lock(fd, 0, SEEK_SET, 0))

#define my_unlock(fd) (Un_lock(fd, 0, SEEK_SET, 0))

Листинг 9.4. Вызов fcntl для получения и снятия блокировки

//lib/lock_reg.c

1 #include "unpipc.h"

2 int

3 lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)

4 {

5 struct flock lock;

6 lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */

7 lock.l_start = offset; /* сдвиг по отношению к l_whence */

8 lock.l_whence = whence; /* SEEK SET. SEEK CUR, SEEK END */

9 lock.l_len = len; /* количество байтов (0 – до конца файла) */

10 return(fcnt(fd, cmd, &lock)"); /* –1 в случае ошибки */

11 }

Листинг 9.5. Вызов fcntl для проверки состояния блокировки

//lib/lock_test.c

1 #include "unpipc.h"

2 pid_t

3 lock_test(int fd, int type, off_t offset, int whence, off_t len)

4 {

5 struct flock lock;

6 lock.l_type = type; /* F_RDLCK or F_WRLCK */

7 lock.l_start = offset; /* сдвиг по отношению к l_whence */

8 lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */

9 lock.l_len = len; /* количество байтов. 0 – до конца файла */

10 if (fcntl(fd, F_GETLK, &lock) == –1)

11 return(-1); /* непредвиденная ошибка */

12 if (lock.l_type == F_UNLCK)

13 return(0); /* false, область не заблокирована другим процессом */

14 return(lock.l_pid); /* true, возвращается положительный PID процесса. заблокировавшего ресурс */

15 }

9.4. Рекомендательная блокировка

Блокировка записей по стандарту Posix называется рекомендательной. Ядро хранит информацию обо всех заблокированных различными процессами файлах, но оно не предотвращает запись в заблокированный на чтение процесс. Ядро также не предотвращает чтение из файла, заблокированного на запись. Процесс может игнорировать рекомендательную блокировку (advisory lock) и действовать по своему усмотрению (если у него имеются соответствующие разрешения на чтение и запись).

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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