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

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

Программа semops

в листинге 11.5 приведен текст программы semops, позволяющей выполнять последовательность действий над набором семафоров.

Параметры командной строки

7-19 Параметр -п соответствует установленному флагу IPC NOWAIT для каждой операции, а параметр -и аналогичным образом позволяет указать для каждой операции флаг SEMUNDO, Обратите внимание, что функция semop позволяет указывать свой набор флагов для каждого элемента структуры sembuf (то есть для каждой из операций в отдельности), но для простоты мы в нашей программе задаем одинаковые флаги для всех операций.

Выделение памяти под набор операций

20-29 После открытия семафора вызовом semget мы выделяем память под массив структур sembuf, по одному элементу на каждую операцию из командной строки, В отличие от предыдущих двух программ эта позволяет пользователю задать меньше команд, чем имеется семафоров в наборе.

Выполнение операций

30 Вызов semop выполняет последовательность операций над семафорами набора.

Листинг 11.5. Программа semops

svsem/semops.c

1 finclude unpipc.h

2 int

3 maindnt argc. char **argv)

5 int c. i. flag, semid. nops:

6 struct sembuf *ptr:

7 flag = 0;

8 while ( (c = GetoptCargc. argv. nu )) != -1) {

9 switch (c) {

10 case n:

11 flag 1= IPC NOWAIT; /* для всех операций */

12 break:

13 case u:

14 flag 1= SEM UNDO; /* для всех операций */

15 break:

16 }

17 }

18 if (argc - optind < 2) /* argc - optind = количество оставшихся

аргументов */

19 err quit( usage; semops [ -n ] [ -u ] <pathname> operation ... );

20 semid = Semget(Ftok(argv[optind]. 0). 0. 0):

21 optind++;

22 nops = argc - optind;



23 /* выделение памяти под операции, сохранение их в массиве и выполнение */

24 ptr = CallocCnops. sizeofCstruct sembuf)):

25 for (i = 0; i < nops; i++) {

26 ptr[i].sem num = i;

27 ptr[i].sem op = atoi(argv[optind + i]); /* <0. 0. or >0 */

28 ptr[i].sem f1g - flag;

29 }

30 Semop(semid. ptr. nops):

31 exit(O):

32 }

Примеры

Теперь мы продемонстрируем работу пяти приведенных выше программ и исследуем некоторые свойства семафоров System V:

Solaris % touch /tmp/rich Solaris % semcreate -e /tmp/rich 3 Solaris % semsetvalues /tmp/rich 12 3 Solaris % semgetvalues /tmp/rich

semval[0] = 1 semval[1] = 2 semval[2] - 3

Сначала мы создали файл с именем /tmp/rich, который использовался при вызове ftok для вычисления идентификатора набора семафоров. Программа semcreate создает набор с тремя элементами. Программа semsetvalues устанавливает значения этих элементов (1, 2 и 3), а semgetval ues выводит их значения.

Теперь продемонстрируем атомарность выполнения последовательности операций над набором:

Solaris % semops -n /tmp/rich -1 -2 -4

semctl error: Resource temporarily unavailable Solaris % semgetvalues /tmp/rich semval[0] = 1 semval[1] - 2 semval [2] = 3

В командной строке мы указываем параметр, отключающий блокировку (-п), и три операции, каждая из которых уменьшает одно из значений набора семафоров. Первая операция завершается успешно (мы можем вычесть 1 из значения первого элемента набора, потому что до вычитания оно равно 1), вторая операция также проходит (вычитаем 2 из значения второго семафора, равного 2), но третья операция выполнена быть не может (мы не можем вычесть 4 из значения третьего семафора, потому что оно равно 3). Поскольку последняя операция последовательности не может быть выполнена и поскольку мы отключили режим блокирования процесса, функция возвращает ошибку EAGAIN. Если бы мы не указали флаг отключения блокировки, выполнение процесса было бы приостановлено до тех пор, пока операция вычитания не стала бы возможной. После этого мы проверяем, чтобы ни одно из значений семафоров набора не изменилось. Хотя первые две операции и могли бы быть выполнены, ни одна из трех на самом деле произведена не была, поскольку последняя операция была некорректной. Атомарность semop и означает, что выполняются либо все операции, либо ни одна из них.



Теперь продемонстрируем работу флага SEM UNDO:

Solaris % semsetvalues /tmp/n ch 12 3 устанавливаем конкретные значения

Solaris % semops -u /tmp/rich -1 -2 -3 для каждой операции указывается флаг SEMJJNDO

Solaris % semgetvalues /tmp/rich

semval[0] - 1 все произведенные изменения были сброшены

после завершения работы программы semps

semval[1] = 2 semval[2] = 3

Solaris % semops /tmp/rich -1 -2 -3 теперь мы не указываем флаг SEMJJNDO Solaris % semgetvalues /trap/rich semval[0] = 0 semval[1] = 0 semval[2] = 0

Сначала мы заново устанавливаем значения семафоров в наборе равными 1,2 и 3 с помощью программы semsetval ues, а затем запускаем программу semops с операциями -1,-2, -3, При этом все три значения семафоров становятся нулевыми, но, так как мы указали параметр -и при вызове semops, для всех трех операций устанавливается флаг SEMUNDO, При этом значения semadj для элементов набора семафоров становятся равными 1, 2 и 3 соответственно. После завершения программы semops эти значения добавляются к значениям семафоров, в результате чего их значения становятся равными 1, 2 и 3, как будто мы и не запускали программу, В этом мы убеждаемся, запустив semgetval ues. Затем мы снова запускаем semops, но уже без параметра -и, и убеждаемся, что при этом значения семафоров становятся нулевыми и остаются таковыми даже после выхода из программы.

11.6. Блокирование файлов

с помощью семафоров System V можно реализовать еще одну версию функций myjock и ту unlock из листинга 10.10, Новый вариант приведен в листинге 11.6,

Листинг 11.6. Блокировка файлов с помощью семафоров System V

lock/locksvsem.c

1 finclude unpipc.h

2 fdefine LOCK PATH /tmp/svsemlock

3 fdefine MAXJRIES 10

4 int semid, initflag;

5 struct sembuf postop. waitop;

6 void

7 myjockdnt fd)

9 int oflag, i;

10 union semun arg;

11 struct semid ds seminfo;

12 if (initflag - 0) {

13 oflag = IPC JREAT IPCJXCL SVSEM MODE;

14 if ( (semid = semget(Ftok(LOCKJATH, 0), 1, oflag)) >- 0) {

15 /* этот процесс создал семафор первым, он же его и инициализирует */

16 arg.val - 1;



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.
Копирование материалов разрешено исключительно при условии цититирования.