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

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

Листинг 11.7 (продолжение)

46 /* сколько всего семафоров можно создать? */

47 semmns = 0;

48 for (i = 0; i < semmni; i++) {

49 sid[i] - sefflget(IPC PRIVATE, semmsl, SVSEM MODE IPC CREAT);

50 if (sid[i] -1) {

51 /*

52 До этого в наборе было semmsl элементов,

53 но теперь мы уменьшаем количество элементов на 1 и смотрим,

54 не получится ли создать семафор

55 */

56 for (j - semmsM; j > 0; j--) {

57 sid[i] = semget(IPC PRIVATE, j, SVSEM MODE IPC CREAT);

58 if (sid[i] != -1) {

59 semmns += j;

60 printf( max of d semaphoresVn , semmns);

61 SemctUsid[i], 0, IPC RMID);

62 goto done;

63 }

64 }

65 err qmt( j reached 0, semmns = d , semmns);

66 }

67 semmns += semmsl;

68 }

69 printf( max of d semaphoresVn , semmns);

70 done:

71 for (j = 0: j < i; j++)

72 SemctUsid[j], 0, IPC RMID);

73 /* определяем количество операций за вызов semopO */

74 semid - Semget(IPC PRIVATE, semmsl, SVSEM MODE IPC CREAT);

75 for (i = 1; i <= MAX NOPS; i++) {

76 ops[i-l].sem num = i-1;

77 ops[i-l].sem op = 1;

78 ops[i-l].sem f1g = 0;

79 if (semop(semid, ops, i) == -1) {

80 if (errno !- E2BIG)

81 err sys( expected E2BIG from semop ); 62 semopn = i-1;

83 printf( max of %й operations per semop()\n , semopn);

84 break;

85 }

86 }

87 SemctUsemid, 0, IPC RMID);

88 /* определение максимального значения semadj */

89 /* создание одного набора с одним семафором */

90 semid = Semget(IPC PRIVATE, 1, SVSEM MODE IPC CREAT);

91 arg.val - semvmx;

92 SemctUsemid, 0, SETVAL, arg): /* устанавливаем значение на максимум */

93 for (i = semvmx-1; i > 0; i--) {

94 ops[0].sem num = 0:

95 ops[0].sem op = -i;

96 ops[0].sem flg = SEM UNDO;

97 if (semop(semid, ops, 1) != -1) {

98 semaem = i;

99 printf( max value of adjust-on-exit = d\n , semaem);



100 break;

101 }

102 }

103 SemctKsemid, О, IPC RMID);

104 /* определение максимального количества структур UNDO */

105 /* создаем один набор с одним семафором и инициализируем нулем */

106 semid = Seniget(IPC PRIVATE, 1, SVSEM MODE IPC CREAT);

107 arg.val = 0;

108 SemctKsemid, 0, SETVAL, arg); /* установка значения семафора в О */

109 Pipe(pipefd);

110 child = Manoc(MAX NPROC * sizeof (pi d t));

111 for (i = 0; i < MAX NPROC; i++) {

112 if ( (chi1d[i] = forkO) == -1) {

113 semmnu = i - 1:

114 printf( fork failed, semmnu at least d\n , semmnu);

115 break;

116 } else if (chi1d[i] == 0) {

117 ops[0].sem num = 0; /* дочерний процесс вызывает

senrapO */

118 ops[0].sem op = 1;

119 ops[0].sem f1g = SEMJNDO;

120 j = senrap(semid, ops, 1); /* 0 в случае успешного завершения, -1 -

в случае ошибки */

121 Write(pipefd[l], &j, sizeof(j));

122 s1eep(30): /* ожидает завершения родительским

процессом */

123 exit(O); /* на всякий случай */

124 }

125 /* родительский процесс считывает результат вызова senrapO */

126 Read(pipefd[0], &j, sizeof(j)):

127 if (j -1) {

128 semmnu = i;

129 printf( max # undo structures = d\n , semmnu):

130 break:

131 }

132 }

133 SemctKsemid, 0, IPCJMID):

134 for (j = 0: j <= i && chi1d[j] > 0: j++)

135 Ki1Kchi1d[j], SIGINT);

136 /* определение максимального количества записей корректировки на процесс */

137 /* создание одного набора с максимальным количеством семафоров */

138 semid = Semget(IPCJRIVATE, semmsK SVSEM MODE IPCJREAT);

139 for (i - 0: i < semmsl; i++) {

140 arg.val = 0:

141 SemctKsemid, i, SETVAL, arg): /* установка значения семафора в О */

142 ops[i].sem num - i;

143 ops[i].sem op = 1: /* добавляем 1 к значению семафора */

144 ops[i].semJ1 g - SEMJNDO:

145 if (semop(semid, ops, i+1) == -1) {

146 semume = i:

147 printf( max # undo entries per process = dVn , semume):

148 break:

149 }



Листинг 11.7 (продолжение)

151 SemctUsemid, О, IPC RMID);

152 exit(O);

153 }

11.8. Резюме

у семафоров System V имеются следующие отличия от семафоров Posix:

1, Семафоры System V представляют собой набор значений. Последовательность операций над набором семафоров либо выполняется целиком, либо не выполняется вовсе,

2, К любому элементу набора семафоров могут быть применены три операции: проверка на нулевое значение, добавление некоторого значения к текущему и вычитание некоторого значения из текущего (в предположении, что значение остается неотрицательным). Для семафоров Posix определены только операции увеличения и уменьшения значения семафора на 1 (в предположении, что значение остается неотрицательным).

3, Создание семафора System V имеет некоторую особенность, заключающуюся в необходимости выполнения двух вызовов для создания и инициализации семафора, что может привести к ситуации гонок,

4, Семафоры System V предоставляют возможность отмены операции с ними (undo) после завершения работы процесса.

Упражнения

1, Листинг 6,6 представлял собой измененный вариант листинга 6,4, в котором программа принимала идентификатор очереди вместо полного имени файла. Мы продемонстрировали, что для получения доступа к очереди System V достаточно знать только ее идентификатор (предполагается наличие достаточных разрешений). Проделайте аналогичные изменения с программой в листинге И,5 и посмотрите, верно ли вышесказанное для семафоров System V,

2, Что произойдет с программой в листинге 11,6, если файл LOCKPATH не будет существовать?



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