26.6.1. Создание множества семафоров

26.6.1. Создание множества семафоров

Для создания множества семафоров или подключения к уже существующему множеству используется системный вызов semget():

int semget(key_t key, int nsems, int semflg);

Первый аргумент — это ключ IPC, который, как обычно, создается системным вызовом ftok(). Он сравнивается с ключами других семафоров и в зависимости от значения semflg решается, создавать новое множество или подключиться к уже существующему. Значение semflg:

? IPC_CREAT — создать новое множество семафоров;

? IPC_EXCL — при использовании с IPC_CREAT порождает ошибку, если семафор уже существует.

При создании семафора, как и при создании очереди сообщений, мы можем указать права доступа:

IPC_CREAT | 0660

Второй аргумент системного вызова semget() задает требуемое количество семафоров. Оно ограничено в файле sem.h:

#define SEMMSL 32 /* <= 512 */

Данный аргумент игнорируется, если вы подключаетесь к уже существующему множеству, а не создаете новое.

Функция semget() возвращает идентификатор семафора или -1 в случае ошибки. Переменная errno устанавливается следующим образом:

? EACCESS — у вас не хватает полномочий для выполнения операции;

? EEXISTS — множество существует, его нельзя создать;

? EIDRM — множество помечено для удаления;

? ENOENT — множество не существует, не было ни одной операции IPC_CREAT;

? ENOMEM — не хватает памяти;

? ENOSPC — достигнуто максимальное количество семафоров.

Функция для открытия существующего семафора может выглядеть так:

void open_sem(int *sid, key_t key) {

 if ((*sid = semget(key, 0, 0666)) == -1) {

  printf("Семафор не существует !!!! ");

  exit(1);

 }

}

Для создания множества семафоров можно использовать следующую функцию:

void create_sem(int *sid, key_t key, int n) {

 int c=0; /* счетчик */

 union semun sems;

 if (n > SEMMSL) {

  printf("Превышен лимит. Максимальное число семафоров %d ", SEMMSL);

  exit(1);

 }

 if ((*sid =

  semget(key, n, IPC_CREAT|IPC_EXCL|0666)) == -1) {

  printf("Множество уже существует ");

  exit(1);

 }

 sems.val = SEM_RESOURCE_MAX;

 /* Инициализируем все элементы одним значением */

 semctl(*sid, c, SETALL, sems);

 /* Если нужно установить разные значения,

  нужно использовать SETVAL, например

  for (c=0; c<n; c++)

   semctl(*sid, c, SETVAL, sems);

 */

}

Данный текст является ознакомительным фрагментом.