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);
*/
}
Данный текст является ознакомительным фрагментом.