Лекция: I. Семафоры.

Для работы с семафорами поддерживаются три системных вызова:

  • semget() для создания и получения доступа к набору семафоров;
  • semop() для манипулирования значениями семафоров (это тот системный вызов, который позволяет процессам синхронизоваться на основе использования семафоров
  • semctl() для выполнения разнообразных управляющих операций над набором семафоров

Прототипы перечисленных системных вызовов описаны в файлах

#include <sys/ipc.h>

#include <sys/sem.h>

Системный вызов semget() имеет следующий синтаксис:

semid = int semget(key_t key, int count, int flag),

параметрами которого является ключ (key) набора семафоров и дополнительные флаги (flags), определенные в <sys/ipc.h>, число семафоров в наборе семафоров (count), обладающих одним и тем же ключом. Системный вызов возвращает идентификатор набора семафоров semid. После вызова semget() индивидуальный семафор идентифицируется идентификатором набора семафоров и номером семафора в этом наборе. Флаги системного вызова semget() приведены ниже в таблице.

Таблица

Флаги системного вызова semget()

IPC_CREAT Semget создает новый семафор для данного ключа. Если флаг IPC_CREAT не задан, а набор семафоров с указанным ключом уже существует, то обращающийся процесс получит идентификатор существующего набора семафоров.
IPC_EXLC Флаг IPC_EXLC вместе с флагом IPC_CREAT предназначен для создания (и только для создания) набора семафоров. Если набор семафоров уже существует, Semget возвратит -1, а системная переменная errno будет содержать значение EEXIST.

Младшие 9 бит флага задают права доступа к набору семафоров.

Системный вызов semctl() имеет формат

int semctl (int semid, int sem_num, int command, union semun arg),

где semid — это идентификатор набора семафоров, sem_numb — номер семафора в группе, command — код операции, а arg — указатель на структуру, содержимое которой интерпретируется по-разному, в зависимости от операции.

Структура msg имеет вид:

union semun { int val;

struct semid_ds *buf;

unsigned short *array; };

С помощью semctl() можно

  • уничтожить набор семафоров или индивидуальный семафор в указанной группе (IPC_RMID);
  • вернуть значение отдельного семафора (GETVAL) или всех семафоров (GETALL);
  • установить значение отдельного семафора (SETVAL) или всех семафоров (SETALL);
  • вернуть число семафоров в наборе семафоров (GETPID).

Основным системным вызовом для манипулирования семафором является

int semop (int semid, struct sembuf *op_array, count),

где semid — это ранее полученный дескриптор группы семафоров, op_array — массив структур sembuf, определенных в файле <sys/sem.h.h> и содержащих описания операций над семафорами группы, а count — размер этого массива. Значение, возвращаемое системным вызовом, является значением последнего обработанного семафора. Каждый элемент массива op_array имеет следующую структуру (структура sembuf):

  • номер семафора в указанном наборе семафоров
  • операция над семафором;
  • флаги.

Если указанные в массиве op_array номера семафоров не выходят за пределы общего размера набора семафоров, то системный вызов последовательно меняет значение семафора (если это возможно) в соответствии со значением поля «операция». Возможны три случая:

1. Отрицательное значение sem_op.

  • Если значение поля операции sem_op отрицательно, и его абсолютное значение меньше или равно значению семафора semval, то ядро прибавляет это отрицательное значение к значению семафора.
  • Если в результате значение семафора стало нулевым, то ядро активизирует все процессы, ожидающие нулевого значения этого семафора.
  • Если же значение поля операции sem_op по абсолютной величине больше семафора semval, то ядро увеличивает на единицу число процессов, ожидающих увеличения значения семафора и усыпляет текущий процесс до наступления этого события.

2. Положительное значение sem_op.

Если значение поля операции sem_op положительно, то оно прибавляется к значению семафора semval, а все процессы, ожидающие увеличения значения семафора, активизируются (пробуждаются в терминологии UNIX).

3. Нулевое значение sem_op.

  • Если значение поля операции sem_op равно нулю, то если значение семафора semval также равно нулю, выбирается следующий элемент массива op_array.
  • Если же значение семафора semval отлично от нуля, то ядро увеличивает на единицу число процессов, ожидающих нулевого значения семафора, а обратившийся процесс переводится в состояние ожидания

При использовании флага IPC_NOWAIT ядро ОС UNIX не блокирует текущий процесс, а лишь сообщает в ответных параметрах о возникновении ситуации, приведшей бы к блокированию процесса при отсутствии флага IPC_NOWAIT.

еще рефераты
Еще работы по информатике