Вход/Регистрация
Linux: Полное руководство
вернуться

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

Шрифт:

Функция для открытия существующего семафора может выглядеть так:

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;

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

 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 равна:

  • Читать дальше
  • 1
  • ...
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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