Linux: Полное руководство
Шрифт:
Как и в случае с очередями сообщений, для семафоров в ядре Linux есть своя структура — semid_ds, которая описана в файле
Обратите внимание: в структуре есть указатель на первый семафор. Тип указателя — sem. Данный тип описывает семафор:
♦ sem_pid
PID процесса, который произвел последнюю операцию над семафором.
♦ sem_semval
Текущее значение семафора.
♦ sem_semncnt
Число процессов, ожидающих увеличения значения семафора, то есть освобождения ресурсов.
♦ sem_semzcnt
Число процессов, ожидающих освобождения всех ресурсов.
26.6.1. Создание множества семафоров
Для создания множества семафоров или подключения к уже существующему множеству используется системный вызов semget:
Первый аргумент — это ключ IPC, который, как обычно, создается системным вызовом ftok. Он сравнивается с ключами других семафоров и в зависимости от значения semflg решается, создавать новое множество или подключиться к уже существующему. Значение semflg:
♦ IPC_CREAT — создать новое множество семафоров;
♦ IPC_EXCL — при использовании с IPC_CREAT порождает ошибку, если семафор уже существует.
При создании семафора, как и при создании очереди сообщений, мы можем указать права доступа:
I
Второй аргумент системного вызова semget задает требуемое количество семафоров. Оно ограничено в файле sem.h:
Данный аргумент игнорируется, если вы подключаетесь к уже существующему множеству, а не создаете новое.
Функция semget возвращает идентификатор семафора или -1 в случае ошибки. Переменная
♦ EACCESS — у вас не хватает полномочий для выполнения операции;
♦ EEXISTS — множество существует, его нельзя создать;
♦ EIDRM — множество помечено для удаления;
♦ ENOENT — множество не существует, не было ни одной операции IPC_CREAT;
♦ ENOMEM —
не хватает памяти;♦ ENOSPC — достигнуто максимальное количество семафоров.
Функция для открытия существующего семафора может выглядеть так:
Для создания множества семафоров можно использовать следующую функцию:
26.6.2. Выполнение операций над семафорами
Для выполнения операций над множеством семафоров служит системный вызов semop:
Первый аргумент — это идентификатор семафора, возвращаемый вызовом semget. Второй — это массив операций, которые нужно выполнить над семафорами. Последний аргумент — это количество операций в массиве.
Второй аргумент представляет собой массив типа sembuf:
♦ sem_num
Номер семафора, над которым нужно выполнить операцию
♦ sem_op
Выполняемая операция. Может быть отрицательным или положительным числом. Если число отрицательно, значение семафора будет уменьшено, а если положительным — увеличено. Не забывайте, освобождая ресурс, увеличивать значение семафора — за вас никто это не сделает. Если sem_op = 0, то процесс «заснет» и не «проснется» до тех пор, пока значение семафора не станет 0.