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

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

Шрифт:

9.6. Приоритет чтения и записи

В нашей реализации блокировок чтения-записи в разделе 8.4 приоритет предоставлялся ожидающим записи процессам. Теперь мы изучим детали возможного решения задачи читателей и писателей с помощью блокировки записей fcntl. Хочется узнать, как обрабатываются накапливающиеся запросы на блокировку, когда ресурс уже заблокирован. Стандарт Posix этого никак не оговаривает.

Пример: блокировка на чтение при наличии в очереди блокировки на запись

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

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

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

Рис. 9.2. Определение возможности установки блокировки на чтение при наличиивочереди блокировки на запись

Листинг 9.6. Определение возможности установки блокировки на чтение при наличии в очереди блокировки на запись

//lock/test2.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 int fd;

6 fd = Open("test1.data", O_RDWR | O_CREAT, FILE_MODE);

7 Read_lock(fd, 0, SEEK_SET, 0); /* родительский процесс блокирует весь файл на чтение */

8 printf("%s: parent has read lock\n", Gf_time);

9 if (Fork == 0) {

10 /* первый дочерний процесс */

11 sleep(1);

12 printf("%s: first child tries to obtain write lock\n", Gf_time);

13 Writew_lock(fd, 0, SEEK_SET, 0); /* здесь он будет заблокирован */

14 printf("%s: first child obtains write lock\n", Gf_time);

15 sleep(2);

16 Un_lock(fd, 0, SEEK_SET, 0);

17 printf("ls: first child releases write lock\n", Gf_time);

18 exit(0);

19 }

20 if (Fork == 0) {

21 /* второй дочерний процесс */

22 sleep(3);

23 printf("%s: second child tries to obtain read lock\n", Gf_time);

24 Readw_lock(fd, 0, SEEK_SET, 0);

25 printf("%s: second child obtains read lock\n", Gf_time);

26 sleep(4);

27 Un_lock(fd, 0, SEEK_SET, 0);

28 printf("%s: second child releases read lock\n", Gf_time);

29 exit(0);

30 }

31 /* родительский процесс */

32 sleep(5);

33 Un_lock(fd, 0, SEEK_SET, 0);

34 printf("%s: parent releases read lock\n", Gf_time);

35 exit(0);

36 }

Родительский процесс открывает файл и получает блокировку на чтение

6-8 Родительский процесс открывает файл и устанавливает блокировку на чтение для всего файла целиком. Обратите внимание, что мы вызываем read_lock (которая возвращает ошибку в случае недоступности ресурса), а не readw_lock (которая ждет его освобождения), потому что мы ожидаем, что эта блокировка будет установлена немедленно. Мы также выводим значение текущего времени функцией gf_time [24, с. 404], когда получаем блокировку.

  • Читать дальше
  • 1
  • ...
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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