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

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

Жанры

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

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

Шрифт:

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

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

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

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

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

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

 */

}

26.6.2. Выполнение операций над семафорами

Для выполнения операций над множеством семафоров служит системный вызов semop:

int semop(int semid, struct sembuf *sops, unsigned nsops);

Первый аргумент — это идентификатор семафора, возвращаемый вызовом semget. Второй — это массив операций, которые нужно выполнить над семафорами. Последний аргумент — это количество операций в массиве.

Второй аргумент представляет собой массив типа sembuf:

struct sembuf {

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

 short sem_op; /* операция над семафором */

 short sem_flg; /* флаги */

};

♦ sem_num

Номер семафора, над которым нужно выполнить операцию

♦ sem_op

Выполняемая операция. Может быть отрицательным или положительным числом. Если число отрицательно, значение семафора будет уменьшено, а если положительным — увеличено. Не забывайте, освобождая ресурс, увеличивать значение семафора — за вас никто это не сделает. Если sem_op = 0, то процесс «заснет» и не «проснется» до тех пор, пока значение семафора не станет 0.

♦ sem_flg

Флаги операции, например, IPC_NOWAIT. Если IPC_NOWAIT не установлен, то процесс «заснет» до тех пор, пока не освободится указанное количество ресурсов (пока другой процесс не освободит их).

Чтобы лучше понять, что такое semop, вернемся к нашим принтерам. Пусть у нас есть всего один принтер, умеющий выполнять только одно задание за раз. Начальное значение семафора принтера будет равно 1.

Перед посылкой задания на принтер нужно убедиться, что он свободен, то есть получить от семафора значение 1. Заполним массив sembuf необходимой для выполнения операции информацией:

struct sembuf prn_lock = {0, -1, IPC_NOWAIT};

Здесь 0 — это номер семафора: у нас всего один принтер, а нумерация начинается с нуля.
– 1 — это операция, запрашивающая единицу ресурса. Если принтер свободен, то после выполнения этой операции значение семафора принтера будет равно 0.

Мы также установили флаг IPC_NOWAIT, чтобы вызов прошел немедленно. Если принтер занят, вызов вернет ошибку:

if (semop(sid, &prn_lock, 1) == -1)

 printf("Принтер занят\n");

Первый аргумент — это идентификатор объекта IPC, второй — это массив операций. Последний аргумент semop говорит о том, что у нас есть только одна структура типа sembuf, то есть нам нужно выполнить только одну операцию.

После выполнения задания мы должны сообщить семафору об освобождении ресурса:

struct sembuf prn_unlock ={0, 1, IPC_NOWAIT};

semop(sid, &prn_unlock, 1);

В случае успеха, когда выполнены все операции, системный вызов semop возвращает 0. В случае ошибки возвращается -1, а errno равна:

♦ E2BIG — количество операций (аргумент nsops) превышает разрешенное число операций;

♦ EACCESS — не хватает полномочий;

♦ EAGAIN — операция не может быть выполнена (при использовании флага IPC_NOWAIT), такую операцию нужно повторить снова;

♦ EFAULT — указатель sops указывает на ошибочный адрес;

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

♦ EINTR — прервано сигналом;

♦ EINVAL — неверный semid;

♦ ENOMEM — не хватает памяти для создания структуры Undo-операции;

♦ ERANGE — значение семафора вышло за пределы допустимых значений.

26.6.3. Контроль семафора

Для контроля семафора используется системный вызов semctl:

int semctl(int semid, int semnum, int cmd, union semun arg);

Первый аргумент — это идентификатор семафора, второй — номер семафора во множестве семафоров (нумерация начиняется с 0). В отличие от очереди сообщений, где достаточно было указать только идентификатор очереди, при работе с семафорами нужно обязательно указывать номер конкретного семафора, над которым вы хотите выполнить операцию. Третий аргумент — это команда, которую нужно выполнить над семафором. Возможные команды представлены в таблице 26.1.

Команды управления семафорами Таблица 26.1

Команда Назначение
IPC_STAT Запоминает структуру semid_ds для множества по адресу buf объединения semun (чуть позже мы подробно рассмотрим эту структуру и объединение semun)
IPC_SET Устанавливает значение члена ipc_perm структуры semid_ds
IPC_RMID Удаляет множество
GETALL Позволяет получить значения всех семафоров. Значения возвращаются в виде массива unsigned short, на который указывает член объединения array
GETNCNT Возвращает число процессов, которые ожидают ресурсы в данный момент
GETPID Возвращает PID процесса, выполнившего последний вызов semop
GETVAL Возвращает значение одного семафора
GETZCNT Возвращает число процессов, которые ожидают полного освобождения ресурса
SETALL Устанавливает значение семафоров. Значения берутся из члена array объединения semun
SETVAL Устанавливает значение конкретного семафора. Значение берется из элемента val объединения semun

Последний аргумент — это объединение (union) аргументов, которые можно использовать для управления семафором. Рассмотрим подробнее это объединение, объявленное в файле

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

union semun {

 int val; /* значение для SETVAL */

 struct semid_ds *buf; /* буфер для IPC_STAT и IPC_SET */

 ushort *array; /* массив для GETALL и SETALL */

 struct seminfo *__buf; /* буфер для IPC_INFO */

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

Хозяин Стужи 2

Петров Максим Николаевич
2. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.75
рейтинг книги
Хозяин Стужи 2

Я еще царь. Книга XXX

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

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Эволюционер из трущоб. Том 11

Панарин Антон
11. Эволюционер из трущоб
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Эволюционер из трущоб. Том 11

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Наследник павшего дома. Том IV

Вайс Александр
4. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том IV

Санек 3

Седой Василий
3. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 3

Моя простая курортная жизнь 5

Блум М.
5. Моя простая курортная жизнь
Любовные романы:
эро литература
5.00
рейтинг книги
Моя простая курортная жизнь 5

Деревенщина в Пекине 2

Афанасьев Семён
2. Пекин
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Деревенщина в Пекине 2

Лекарь Империи 10

Карелин Сергей Витальевич
10. Лекарь Империи
Фантастика:
городское фэнтези
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Лекарь Империи 10

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой

Я снова граф. Книга XI

Дрейк Сириус
11. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я снова граф. Книга XI

Вечный. Книга III

Рокотов Алексей
3. Вечный
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга III