Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 [ 71 ] 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

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

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

дочерний процесс № 1

дочерний процесс № 2

6-7-8-

получение блокировки на чтение

освобождает ресурс

попытка установить блокировку на запись

получает блокировку на запись

освобождает ресурс

получение блокировки на чтение

освобождает ресурс

время

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

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

lock/test2.c

1 linclude unpipc.h

2 int

3 mainCint argc, char **argv)

5 int fd;

6 fd = Open( testl.data , 0 RDWR 0 CREAT, FILE MODE);

7 Read lock(fd, 0, SEEK SET. 0): /* родительский процесс блокирует весь

файл на чтение */



8 printf( *s: parent has read lock\n . Gf time()):

9 if (ForkO == 0) {

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

11 sleep(l):

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 UnJock(fd. 0. SEEKJET. 0):

17 printf( *s: first child releases write lock\n . Gf time())-.

18 exit(O);

19 }

20 if (ForkO == 0) {

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

22 sleep(3);

23 printfCs: second child tries to obtain read 1ock\n . Gf time()):

24 ReadwJock(fd. 0, SEEKJET, 0):

25 printf( *s: second child obtains read lock\n . GfJimeO):

26 sleep(4):

27 UnJock(fd. 0. SEEKJET, 0):

28 printf( *s: second child releases read lock\n . GfJimeO);

29 exit(O):

30 }

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

32 sleep(5);

33 UnJock(fd. 0. SEEKJET, 0):

34 pri ntf ( *s; parent releases read lock\n , GfJimeO):

35 exit(O);

36 }

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

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

Первый дочерний процесс

9-19 Порождается первый процесс, который ждет 1 секунду и блокируется в ожидании получения блокировки на запись для всего файла. Затем он устанавливает эту блокировку, ждет 2 секунды, снимает ее и завершает работу.

Второй дочерний процесс

20-30 Порождается второй процесс, который ждет 3 секунды, давая возможность первому попытаться установить блокировку на запись, а затем пытается получить блокировку на чтение для всего файла. По моменту возвращения из функции readw lock мы можем узнать, был ли ресурс предоставлен немедленно или



второму процессу пришлось ждать первого. Блокировка снимается через четыре секунды.

Родительский процесс блокирует ресурс 5 секунд

31-35 Родительский процесс ждет пять секунд, снимает блокировку и завершает работу.

На рис. 9.2 приведена временная диаграмма выполнения программы в Solaris 2.6, Digital Unix 4.0В и BSD/OS 3.1. Как видно, блокировка чтения предоставляется второму дочернему процессу немедленно, несмотря на наличие в очереди запроса на блокировку записи. Существует вероятность, что запрос на запись так и не будет выполнен, если будут постоянно поступать новые запросы на чтение. Ниже приведен результат выполнения программы, в который были добавлены пустые строки для улучшения читаемости:

alpha % test2

16:32:29.674453: parent has read lock

16:32:30.709197: first child tries to obtain write lock

16:32:32.725810: second child tries to obtain read lock 16:32:32.728739: second child obtains read lock

16:32:34.722282: parent releases read lock

16:32:36.729738: second child releases read lock 16:32:36.735597: first child obtains write lock

16:32:38.736938: first child releases write lock

Пример: имеют ли приоритет запросы на запись перед запросами на чтение?

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

В листинге 9.7 приведен текст нашей тестовой программы, а на рис. 9.3 - временная диаграмма ее выполнения.

Листинг 9.7. Есть ли у писателей приоритет перед читателями

lock/test3.c

1 linclude unpipc.h

2 int

3 mainCint argc. char **argv)

5 int fd:

6 fd - Open( testl.data . 0 RDWR 0 CREAT. FILE MODE);

7 Write lock(fd. 0. SEEK SET. 0): /* родительский процесс блокирует весь

файл на запись */



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 [ 71 ] 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.