Книга: UNIX: взаимодействие процессов

11.1.Введение

11.1.Введение

В главе 10 мы описывали различные виды семафоров, начав с:

? бинарного семафора, который может принимать только два значения: 0 и 1. По своим свойствам такой семафор аналогичен взаимному исключению (глава 7), причем значение 0 для семафора соответствует блокированию ресурса, а 1 — освобождению.

Далее мы перешли к более сложному виду семафоров:

? семафор-счетчик, значение которого лежит в диапазоне от 0 до некоторого ограничения, которое, согласно Posix, не должно быть меньше 32767. Они использовался для подсчета доступных ресурсов в задаче о производителях и потребителях, причем значение семафора соответствовало количеству доступных ресурсов.

Для обоих типов семафоров операция wait состояла в ожидании изменения значения семафора с нулевого на ненулевое и последующем уменьшении этого значения на 1. Операция post увеличивала значение семафора на 1, оповещая об этом все процессы, ожидавшие изменения значения семафора.

Для семафоров System V определен еще один уровень сложности:

? набор семафоров-счетчиков — один или несколько семафоров, каждый из которых является счетчиком. На количество семафоров в наборе существует ограничение (обычно порядка 25 — раздел 11.7). Когда мы говорим о семафоре System V, мы подразумеваем именно набор семафоров-счетчиков, а когда говорим о семафоре Posix, подразумевается ровно один семафор-счетчик.

Для каждого набора семафоров ядро поддерживает следующую информационную структуру, определенную в файле <sys/sem.h>:

struct semid_ds {
 struct ipc_perm sem_perm; /* разрешения на операции */
 struct sem *sem_base; /*указатель на массив семафоров в наборе */
 ushort sem_nsems; /* количество семафоров в наборе */
 time_t sem_otime; /* время последнего вызова semop(); */
 time_t sem_ctime; /* время создания последнего IPC_SET */
};

Структура ipc_perm была описана в разделе 3.3. Она содержит разрешения доступа для данного семафора.

Структура sem представляет собой внутреннюю структуру данных, используемую ядром для хранения набора значений семафора. Каждый элемент набора семафоров описывается так:

struct sem {
 ushort_t semval; /* значение семафора, неотрицательно */
 short sempid; /* PID последнего процесса, вызвавшего semop(), SETVAL, SETALL */
 ushort_t semncnt; /* количество ожидающих того, что значение семафора превысит текущее */
 ushort_t semzcnt; /* количество ожидающих того, что значение семафора станет равным 0*/
};

Обратите внимание, что sem_base представляет собой указатель на массив структур типа sem — по одному элементу массива на каждый семафор в наборе.

Помимо текущих значений всех семафоров набора в ядре хранятся еще три поля данных для каждого семафора: идентификатор процесса, изменившего значение семафора последним, количество процессов, ожидающих увеличения значения семафора, и количество процессов, ожидающих того, что значение семафора станет нулевым.

ПРИМЕЧАНИЕ

В стандарте Unix 98 данная структура не имеет имени. Приведенное выше имя (sem) взято из реализации System V. 

Любой конкретный семафор в ядре мы можем воспринимать как структуру semid_ds, указывающую на массив структур sem. Если в наборе два элемента, мы получим картину, изображенную на рис. 11.1. На этом рисунке переменная sem_nsems имеет значение 2, а каждый из элементов набора идентифицируется индексом ([0] или [1]). 


Рис. 11.1. Структуры данных ядра для набора семафоров из двух элементов

Оглавление книги


Генерация: 0.066. Запросов К БД/Cache: 0 / 2
поделиться
Вверх Вниз