- •System V ipc
- •Введение
- •Средства System V ipc
- •Структура api System V ipc
- •Общие свойства средств ipc
- •Общие свойства средств ipc - (продолжение)
- •*Get - основные сведения
- •Получение ключа ipc
- •*Ctl - основные сведения
- •*Op - основные сведения
- •Структура очередей сообщений
- •Доступ к очереди сообщений
- •Управление очередью сообщений
- •Msgctl(2) - Пример
- •Формат сообщения
- •Операции - очереди сообщений - msgsnd(2)
- •Операции - очереди сообщений - msgrcv(2)
- •Пример сообщений - отправитель
- •Пример сообщений - получатель
- •Пример сообщений - вывод
- •Семафоры
- •Системные вызовы для работы с семафорами
- •Получение доступа к набору семафоров
- •Получение доступа к семафору - Пример
- •Управление семафорами
- •Semctl(2) - Примеры
- •Инициализировать и удалить семафор - Пример
- •Блокировка ресурса - Пример
- •Набор семафоров - Использование
- •Создание набора семафоров - Пример
- •Операции над набором семафоров — Пример (продолжение)
- •Разделяемая память
- •Разделяемая память
- •Создание/получение разделяемой памяти
- •Управление разделяемой памятью
- •Операции над разделяемой памятью
- •Разделяемая память - Родительский процесс
- •Разделяемая память - Родительский процесс
- •Разделяемая память - Порожденный процесс
- •Разделяемая память - вывод
Semctl(2) - Примеры
В прототипе semctl(2) последний параметр указан как union. Это означает, что тип последнего параметра зависит от значения команды cmd. На следующей странице приведены примеры использования различных значений cmd. Ниже показано, какие типы arg используются с различными командами:
. int val;
SETVAL Эта команда устанавливает значение отдельного семафора в наборе.
. struct semid_ds *buf;
IPC_STAT Эта команда копирует состояние набора семафоров в буфер buf.
IPC_SET Эта команда устанавливает значения хозяина, группы и прав доступа для набора семафоров.
. ushort *array;
GETALL Эта команда получает значения всех семафоров в наборе и помещает их в массив, на который указывает array.
SETALL Устанавливает все семафоры из набора в значения, которые хранятся в массиве array.
. arg не используется
GETVAL Эта команда получает значение семафора с индексом semnum.
GETPID Эта команда получает идентификатор процесса, который совершал последнюю операцию над семафором с индексом semnum.
GETNCNT Эта команда получает количество процессов, ожидающих увеличения значения семафора по сравнению с текущим.
GETZCNT Эта команда получает количество процессов, ожидающих, пока значение семафора не станет 0.
IPC_RMID Эта команда удаляет набор семафоров и его идентификатор. Если какие-то процессы были заблокированы в операциях с этим набором, во всех этих процессах соответствующие вызовы semop(2) вернут ошибку EIDRM.
semctl(2) - ПРИМЕРЫ
. описания и системный вызов для создания набора семафоров
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define ANY 0int semid, rtn;struct semid_ds ds;ushort us[5], init_us[5] = { 0, 6, 7, 1, 4 };...semid = semget(key, 5, IPC_CREAT | 0660);. инициализировать один семафор из набора
semctl(semid, 2, SETVAL, 7);. получить значение одного семафора из набора
/* такой же формат для GETNCNT, GETZCNT, GETPID */rtn = semctl (semid, 2, GETVAL, ANY);. инициализировать все семафоры в наборе
semctl (semid, ANY, SETALL, init_us);. получить все значения семафоров в наборе
semctl (semid, ANY, GETALL, us);. изменить хозяина
/* также изменяются права доступа */semctl (semid, ANY, IPC_STAT, &ds);ds.sem_perm.uid = 51; /* new uid */semctl (semid, ANY, IPC_SET, &ds);. удалить набор семафоров
semctl (semid, ANY, IPC_RMID, ANY);
Инициализировать и удалить семафор - Пример
Это тот же пример, что и выше, но здесь показан код для инициализации семафора и его удаления. Этот фрагмент программы работает так:
32-37 Если эта программа создала набор семафоров, инициализировать его в 1. Как правило, набор семафоров должен быть удален перед выходом из программы, если его инициализация не удалась, но это здесь не показано.
54-60 Cоздатель набора семафоров может удалить его. В нашей программе, по соглашению, удалением семафоров занимается тот же процесс, который их создал. Обратите внимание на использование "пустых" аргументов в тех местах, где соответствующие параметры системных вызовов не используются. Функция sleep(3C) задерживает удаление семафора на 5 секунд, так что другая программа может продолжать работу с ним.
Файл: semdemo.cИНИЦИАЛИЗИРОВАТЬ И УДАЛИТЬ СЕМАФОР - ПРИМЕР1 #include <unistd.h>2 #include <stdlib.h>3 #include <sys/types.h>4 #include <sys/ipc.h>5 #include <sys/sem.h>6 #include <stdio.h>7 #define DUMMY 08 #define COUNT 4910 main(int argc, char *argv[])11 {...32 if (creator) {/* initialize semaphore */33 if (semctl(semid, 0, SETVAL, 1) == -1) {34 perror(argv[0]);35 exit(2);36 }37 }...54 if (creator) {55 sleep(5);56 if(semctl(semid,DUMMY,IPC_RMID,DUMMY) == -1) {57 perror(argv[0]);58 exit(5);59 }60 }61 return(0);62 }
Операции над семафорами
Системный вызов semop(2) производит операции над одним или более семафорами из набора. Операции увеличивают или уменьшают значение семафора на заданную величину, или ожидают, пока семафор не станет нулевым.
Аргументы этого системного вызова таковы:
semid Идентификатор набора семафоров.
sops Адрес массива с элементами типа struct sembuf. Каждый элемент задает одну операцию над одним семафором. По этому адресу должно размещаться nsops таких структур. Эта структура определена следующимобразом:
sys/sem.h:
struct sembuf {ushort sem_num; /* semaphore */short sem_op; /* semaphore operation */short sem_flg; /* operation flags */};Поля этой структуры имеют следующий смысл:
sem_num Индекс семафора, над которым производится операция.
sem_op Если это значение положительно, оно добавляется к текущему значению семафора (POST).
Если sem_op отрицательно, и его абсолютное значение больше текущего значения семафора, операция обычно блокируется. Иначе, из семафора просто вычитается абсолютное значение этого поля (WAIT).
Если sem_op равен нулю, операция блокируется, пока семафор не станет нулевым.
sem_flg Это поле задает дополнительные флаги. Нулевое значение означает, что не задано никаких флагов.Допустимы следующие флаги, объединяемые побитовым ИЛИ:
IPC_NOWAIT Если установлен этот флаг, и операция должна была бы привести к блокировке, semop(2) возвращает неуспех. Этот флаг может быть использован для анализа и изменения значения семафора без блокировки.
SEM_UNDO Если этот флаг установлен, при завершении процесса (как по exit(2), так и по сигналу), операция будет отменена. Это защищает от посмертной блокировки ресурса процессом, который ненормально завершился, не успев освободить ресурс.
Использование SEM_UNDO отменяет операцию над семафором, но не обеспечивает, что ресурс, защищаемый этим семафором, остался в согласованном состоянии после завершения процесса.
Кроме того, нужно иметь в виду, что отмена операций реализована в виде счетчика, в котором накапливаются все значения, добавляемые и вычитаемые процессом при операциях над данным семафором. При завершении процесса этот счетчик просто вычитается из текущего значения семафора. Из этого описания должно быть ясно, что если вы используете флаг SEM_UNDO, его необходимо использовать при всех операциях над этим семафором. Если вы указываете SEM_UNDO только при операциях LOCK, но не при UNLOCK, счетчик отмены может просто переполниться, а его применение к семафору может привести к нежелательным результатам.
При выполнении операции над несколькими семафорами, значения семафоров не меняются, пока не окажется, что все требуемые операции могут быть успешно выполнены. При этом, поведение системы в случае, когда набор операций содержит несколько разных операций над одним и тем же семафором, не стандартизовано. Разные реализации POSIX могут интерпретировать такой набор по разному.
nsops Количество структур в массиве, на который указывает sops. nsops должен всегда быть больше или равен 1. Параметр prctl(1) process.max-sem-ops ограничивает максимальное количество операций в одном наборе.
