Чтение онлайн

на главную - закладки

Жанры

Linux: Полное руководство

Аллен Питер В.

Шрифт:

 if (msgctl(id, IPC_SET, &buf) == -1} {

return(-1);

 }

 return(0);

}

Наша функция возвращает 0 в случае успеха или -1, если произошла ошибка.

На этом обзор средств для работы с очередями сообщений можно считать законченным, теперь с чистой совестью перейдем к следующему средству IPC — семафорам.

26.6. Семафоры

Семафор — это объект IPC, управляющий доступом к общим

ресурсам (устройствам). Семафоры не позволяют одному процессу захватить устройство до тех пор, пока с этим устройством работает другой процесс. Семафор может находиться в двух положениях: 0 (устройство занято) и 1 (устройство свободно).

Одиночный семафор используется редко, практически никогда. Для контроля доступа к ресурсам обычно используются множества семафоров, даже если это множество состоит всего из одного семафора. Например, пусть у нас есть три принтера. Когда вы посылаете задание на печать, диспетчер печати просматривает множество семафоров принтеров и выясняет, есть ли свободный принтер. Если да, то он начинает печатать ваше задание, если же нет, диспетчер ставит ваше задание в очередь печати.

Еще один пример использования семафоров — это счетчики ресурсов. Представим, что вместо принтера есть некий контроллер, позволяющий выполнять 100 заданий одновременно. Когда он свободен, значение семафора равно 100. По мере поступления заданий диспетчер контроллера уменьшает значение семафора на 1, а по мере их выполнения увеличивает на 1. Когда значение достигает 0, новое задание ставится в очередь до освобождения контроллера.

Как и в случае с очередями сообщений, для семафоров в ядре Linux есть своя структура — semid_ds, которая описана в файле

/usr/src/linux/include/linux/sem.h
:

struct semid_ds {

 struct ipc_perm sem_perm; /* права доступа */

 time_t sem_otime; /* время последней операции */

 time_t sem_ctime; /* время последнего изменения */

 struct sem *sem_base; /* указатель на первый семафор */

 struct wait_queue *eventn; /* очереди ожидания */

 struct wait_queue *eventz;

 struct sem_undo *undo; /* запросы undo в этом массиве */

 ushort sem_nsems; /* номера семафоров в массиве */

};

Обратите внимание: в структуре есть указатель на первый семафор. Тип указателя — sem. Данный тип описывает семафор:

struct sem {

 short sempid; /* pid последней операции */

 ushort semval; /* текущее значение семафора */

 ushort semncnt; /* число процессов, ожидающих

освобожд. рес. */

 ushort semzcnt; /* число процессов, ожидающих

освоб. всех рес. */

};

♦ sem_pid

PID процесса, который произвел последнюю операцию над семафором.

♦ sem_semval

Текущее значение семафора.

♦ sem_semncnt

Число процессов, ожидающих увеличения

значения семафора, то есть освобождения ресурсов.

♦ sem_semzcnt

Число процессов, ожидающих освобождения всех ресурсов.

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

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

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

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

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

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

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

I

PC_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("Семафор не существует !!!!\n");

exit(1);

 }

}

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

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

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

 union semun sems;

 if (n > SEMMSL) {

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

exit(1);

 }

 if ((*sid =

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

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

exit(1);

 }

 sems.val = SEM_RESOURCE_MAX;

Поделиться:
Популярные книги

Черный маг императора 3

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Пипец Котенку! 3

Майерс Александр
3. РОС: Пипец Котенку!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Пипец Котенку! 3

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Ты всё ещё моя

Тодорова Елена
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Ты всё ещё моя

S-T-I-K-S. Пройти через туман

Елисеев Алексей Станиславович
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
7.00
рейтинг книги
S-T-I-K-S. Пройти через туман

Имя нам Легион. Том 4

Дорничев Дмитрий
4. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 4

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

Королевская Академия Магии. Неестественный Отбор

Самсонова Наталья
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Королевская Академия Магии. Неестественный Отбор

Последняя Арена 6

Греков Сергей
6. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 6

Жребий некроманта. Надежда рода

Решетов Евгений Валерьевич
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50
рейтинг книги
Жребий некроманта. Надежда рода