Linux: Полное руководство
Шрифт:
Наша функция возвращает 0 в случае успеха или -1, если произошла ошибка.
На этом обзор средств для работы с очередями сообщений можно считать законченным, теперь с чистой совестью перейдем к следующему средству IPC — семафорам.
26.6. Семафоры
Семафор — это объект IPC, управляющий доступом к общим
Одиночный семафор используется редко, практически никогда. Для контроля доступа к ресурсам обычно используются множества семафоров, даже если это множество состоит всего из одного семафора. Например, пусть у нас есть три принтера. Когда вы посылаете задание на печать, диспетчер печати просматривает множество семафоров принтеров и выясняет, есть ли свободный принтер. Если да, то он начинает печатать ваше задание, если же нет, диспетчер ставит ваше задание в очередь печати.
Еще один пример использования семафоров — это счетчики ресурсов. Представим, что вместо принтера есть некий контроллер, позволяющий выполнять 100 заданий одновременно. Когда он свободен, значение семафора равно 100. По мере поступления заданий диспетчер контроллера уменьшает значение семафора на 1, а по мере их выполнения увеличивает на 1. Когда значение достигает 0, новое задание ставится в очередь до освобождения контроллера.
Как и в случае с очередями сообщений, для семафоров в ядре 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 — достигнуто максимальное количество семафоров.
Функция для открытия существующего семафора может выглядеть так:
Для создания множества семафоров можно использовать следующую функцию: