Команда | Назначение |
---|---|
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 */
void *__pad;
};
Первый член этого объединения val используется для установки значения одного семафора при использовании команды SETVAL.
Член buf используется командами IPC_STAT и IPC_SET. Это копия внутренней структуры данных семафора.
Указатель на массив array используется командами GETALL и SETALL для получения или установки значений всех семафоров во множестве.
Последние два члена объединения специфичны только для Linux — в других UNIX-системах вы их не найдете. Эти элементы использует ядро.
В случае успеха системный вызов semctl() возвращает натуральное число, а в случае ошибки -1. Переменная errno равна:
♦ EACCESS — не хватает полномочий;
♦ EFAULT — адрес arg ошибочен;
♦ EIDRM — множество помечено для удаления:
♦ EINVAL — неправильный аргумент semid;
♦ EPERM — у вас нет прав для выполнения команды cmd;
♦ ERANGE — значение семафора вышло за пределы допустимых значений.
Пример получения значения семафора с номером N из множества sid:
int val;
val=semctl(sid, N, GETVAL, 0);
Предположим, что нам нужно вывести состояние всех трех имеющихся принтеров:
int c, val;
for (c=0; x<3; c++) {
val=semctl(sid,c,GETVAL,0);
printf("Принтер %d: %d\n",c,val);
}
А вот код инициализации всех семафоров множества semid:
union semun opts;
int c;
opts.val = 1; /* первоначальное значение семафоров */
for (c=0;c<5;c++) semctl(semid, c, SETVAL, opts);
Довольно часто возникают определенные сложности с установкой прав доступа к множеству семафоров. Рассмотрим следующий код, позволяющий установить права доступа к множеству semid. Права доступа задаются в виде строки, например, «0660».
void sem_change_mode(int semid, char *mode) {
int res;
struct semid_ds semds;
union semun opts;
/* Нужно указать нашу локальную копию структуры */
opts.buf = &semds
if ((res = semctl(semid, 0, IPC_STAT, opts)) == -1) {
printf("Error");
exit(1);
}
printf("Старые права доступа %o\n",
opts.buf->sem_perm.mode);
/* Изменяем права доступа */
sscanf(mode, "%ho", &opts.buf->sem_perm.mode);
/* Обновляем внутреннюю структуру */
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии