Главная страница Взаимодействие нетривиальных процессов Листинг 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 не будет существовать?
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |