138 semid = Semget(IPC_PRIVATE, semmsl, SVSEM_MODE | IPC_CREAT);
139 for (i = 0; i < semmsl; i++) {
140 arg.val = 0;
141 Semctl(semid, i, SETVAL, arg); /* установка значения семафора в 0 */
142 ops[i].sem_num = i;
143 ops[i].sem_op = 1; /* добавляем 1 к значению семафора */
144 ops[i].sem_flg = SEM_UNDO;
145 if (semop(semid, ops, i+1) == –1) {
146 semume = i;
147 printf("max # undo entries per process = %d\n", semume);
148 break;
149 }
150 }
151 Semctl(semid, 0, IPC_RMID);
152 exit(0);
153 }
11.8. Резюме
У семафоров System V имеются следующие отличия от семафоров Posix:
1. Семафоры System V представляют собой набор значений. Последовательность операций над набором семафоров либо выполняется целиком, либо не выполняется вовсе.
2. К любому элементу набора семафоров могут быть применены три операции: проверка на нулевое значение, добавление некоторого значения к текущему и вычитание некоторого значения из текущего (в предположении, что значение остается неотрицательным). Для семафоров Posix определены только операции увеличения и уменьшения значения семафора на 1 (в предположении, что значение остается неотрицательным).
3. Создание семафора System V имеет некоторую особенность, заключающуюся в необходимости выполнения двух вызовов для создания и инициализации семафора, что может привести к ситуации гонок.
4. Семафоры System V предоставляют возможность отмены операции с ними
Упражнения
1. Листинг 6.6 представлял собой измененный вариант листинга 6.4, в котором программа принимала идентификатор очереди вместо полного имени файла. Мы продемонстрировали, что для получения доступа к очереди System V достаточно знать только ее идентификатор (предполагается наличие достаточных разрешений). Проделайте аналогичные изменения с программой в листинге 11.5 и посмотрите, верно ли вышесказанное для семафоров System V.
2. Что произойдет с программой в листинге 11.6, если файл LOCK_PATH не будет существовать?
ЧАСТЬ 4
РАЗДЕЛЯЕМАЯ ПАМЯТЬ
ГЛАВА 12
Введение в разделяемую память
12.1. Введение
Разделяемая память является наиболее быстрым средством межпроцессного взаимодействия. После отображения области памяти в адресное пространство процессов, совместно ее использующих, для передачи данных между процессами больше не требуется участие ядра. Обычно, однако, требуется некоторая форма синхронизации процессов, помещающих данные в разделяемую память и считывающих ее оттуда. В части 3 мы обсуждали различные средства синхронизации: взаимные исключения, условные переменные, блокировки чтения-записи, блокировки записей и семафоры.
ПРИМЕЧАНИЕ
Говоря «не требуется участие ядра», мы подразумеваем, что процессы не делают системных вызовов для передачи данных. Очевидно, что все равно именно ядро обеспечивает отображение памяти, позволяющее процессам совместно ею пользоваться, и затем обслуживает эту память (обрабатывает сбои страниц и т. п.).
Рассмотрим по шагам работу программы копирования файла типа клиент-сервер, которую мы использовали в качестве примера для иллюстрации различных способов передачи сообщений (рис. 4.1).
■ Сервер считывает данные из входного файла. Данные из файла считываются ядром в свою память, а затем копируются из ядра в память процесса.
■ Сервер составляет сообщение из этих данных и отправляет его, используя именованный или неименованный канал или очередь сообщений. Эти формы IPC обычно требуют копирования данных из процесса в ядро.