Главная » 2017 » Ноябрь » 21 » man 2 semctl
01:45
man 2 semctl

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


semctl - операции управления семафорами System V



ОБЗОР


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);



ОПИСАНИЕ


Вызов semctl выполняет операцию, определённую в cmd, над набором семафоров
System V, указанном в semid, или над семафором с номером semnum из этого набора
(семафоры нумеруются, начиная с 0).

Данный вызов имеет три или четыре аргумента, в зависимости от значения cmd. Если
аргументов четыре, то четвертый аргумент arg имеет тип union semun. В вызывающей
программе это объединение должно быть определено следующим образом:

union semun {
int val; /* значение для SETVAL */
struct semid_ds *buf; /* буфер для IPC_STAT, IPC_SET */
unsigned short *array; /* массив для GETALL, SETALL */
struct seminfo *__buf; /* буфер для IPC_INFO
(есть только в Linux) */
};

Структура данных semid_ds определена в <sys/sem.h> следующим образом:

struct semid_ds {
struct ipc_perm sem_perm; /* владелец и права */
time_t sem_otime; /* время последней операции semop */
time_t sem_ctime; /* время последнего изменения */
unsigned long sem_nsems; /* кол-во семафоров в наборе */
};

Структура ipc_perm определена следующим образом (значения полей устанавливаются с
помощью IPC_SET):

struct ipc_perm {
key_t __key; /* ключ, передаваемый в semget(2) */
uid_t uid; /* эффективный UID владельца */
gid_t gid; /* эффективный GID владельца */
uid_t cuid; /* эффективный UID создателя */
gid_t cgid; /* эффективный GID создателя */
unsigned short mode; /* права */
unsigned short __seq; /* порядковый номер */
};

Возможные значения cmd:

IPC_STAT Копирует информацию из структуры данных ядра, связанной с semid, в
структуру semid_ds, расположенную по адресу arg.buf. Аргумент semnum
игнорируется. Вызывающий процесс должен иметь права на чтение набора
семафоров.

IPC_SET Записывает значения некоторых полей структуры semid_ds, на которую
заблокированные в вызове semop(2) (при этом возвращается сообщение об
ошибке, а errno присваивается значение EIDRM). Эффективный идентификатор
пользователя вызывающего процесса должен совпадать с идентификатором
создателя или владельца набора семафоров, или вызывающий должен иметь
расширенные права. Аргумент semnum игнорируется.

IPC_INFO (есть только в Linux)
Возвращает параметры и информацию о системных ограничениях семафоров в
структуре, указанной в arg.__buf. Данная структура имеет тип seminfo,
который определён в <sys/sem.h>, если определён макрос тестирования
свойств _GNU_SOURCE:

struct seminfo {
int semmap; /* количество записей в карте
семафоров; не используется в ядре */
int semmni; /* максимальное количество наборов
семафоров */
int semmns; /* максимальное количество семафоров во
всех наборах семафоров */
int semmnu; /* максимальное количество структур undo
в системе; не используется в ядре */
int semmsl; /* максимальное количество семафоров в
наборе */
int semopm; /* максимальное количество операция для
semop(2) */
int semume; /* максимальное количество записей undo на
процесс; не используется в ядре */
int semusz; /* размер struct sem_undo */
int semvmx; /* максимальное значение семафора */
int semaem; /* максимальное значение, которое может
быть записано для регулирования
семафора (SEM_UNDO) */
};

Значения semmsl, semmns, semopm и semmni можно изменить через
/proc/sys/kernel/sem; подробности в proc(5).

SEM_INFO (есть только в Linux)
Возвращает структуру seminfo, содержащую такую же информацию что и для
IPC_INFO, за исключением того, что следующие поля содержат информацию о
системных ресурсах, потребляемых семафорами: в поле semusz возвращается
количество наборов семафоров, существующих в системе; в поле semaem
возвращается общее количество семафоров во всех наборах семафоров в
системе.

SEM_STAT (есть только в Linux)
Возвращает структуру semid_ds как для IPC_STAT. Однако аргумент semid
содержит не идентификатор семафора, а индекс во внутреннем массиве ядра,
который хранит информацию о всех наборах семафоров в системе.

GETALL Возвращает значение semval (т.е. текущее значение) всех семафоров в
наборе в arg.array. Аргумент semnum игнорируется. Вызывающему процессу
нужны права на чтение набора семафоров.

GETNCNT Возвращает значение semncnt для semnum-того семафора (т.е., число
процессов, ожидающих увеличения значения semval в semnum-ом семафоре
набора). Вызывающему процессу нужны права на чтение набора семафоров.

GETZCNT Возвращает значение semzcnt для semnum-того семафора (т.е., количество
процессов, ожидающих, когда значение semval semnum-того семафора набора
станет равным 0). Вызывающему процессу нужны права на чтение набора
семафоров.

SETALL Устанавливает значение semval всех семафоров набора, используя arg.array
и изменяя также поле sem_ctime структуры semid_ds, связанной с набором.
Записи undo (см. semop(2)) очищаются для изменённых семафоров во всех
процессах. Если изменения значений семафоров приводят к отмене
блокировки в вызове semop(2) других процессов, то эти процессы
пробуждаются. Аргумент semnum игнорируется. Вызывающему процессу нужны
права на запись в набор семафоров.

SETVAL Устанавливает значение semval равным arg.val для semnum-го семафора
набора, изменяя также поле sem_ctime в структуре semid_ds, связанной с
этим набором. Записи undo очищаются для изменённых семафоров во всех
процессах. Если изменения значений семафоров приводят к отмене
блокировки в вызове semop(2) других процессов, то эти процессы
пробуждаются. Аргумент semnum игнорируется. Вызывающему процессу нужны
права на запись в набор семафоров.



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ


При ошибке semctl() возвращает -1, а переменной errno присваивается номер ошибки.

При успешном выполнении системный вызов возвращает положительное значение,
зависящее от cmd:

GETNCNT значение semncnt.

GETPID значение sempid.

GETVAL значение semval.

GETZCNT значение semzcnt.

IPC_INFO самое большое значение индекса, использованного в записи внутреннего
массива ядра, содержащего информацию о всех наборах семафоров (эта
информация может использоваться в повторяющихся операциях SEM_STAT для
получения информации о всех наборах семафоров в системе).

SEM_INFO как для IPC_INFO.

SEM_STAT идентификатор набора семафоров, индекс которого указан в semid.

Для всех остальных значений cmd возвращается 0.



ОШИБКИ


При ошибке errno присваиваются следующие значения:

EACCES Аргумент cmd равен GETALL, GETPID, GETVAL, GETNCNT, GETZCNT, IPC_STAT,
SEM_STAT, SETALL или SETVAL и вызывающий процесс не имеет достаточно прав
на набор семафоров и не имеет мандата CAP_IPC_OWNER в пространстве имён
пользователя, который управляет его пространством имён IPC.

EFAULT Адрес, указанный в arg.buf или arg.array, недоступен.

EIDRM Набор семафоров был удалён.

ERANGE Аргумент cmd имеет значение SETALL или SETVAL и значение, присваиваемое
semval (для какого-то семафора в наборе), меньше нуля или больше, чем
ограничение реализации SEMVMX.



СООТВЕТСТВИЕ СТАНДАРТАМ


POSIX.1-2001, POSIX.1-2008, SVr4.

В POSIX.1 указано, что поле sem_nsems структуры semid_ds имеет тип unsigned short,
и это так на в большинстве других систем. Это было и в Linux 2.2 и более ранних
версиях, но начиная с Linux 2.4 это поле имеет тип unsigned long.



ЗАМЕЧАНИЯ


Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий
POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных
файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на
такие старые системы, может потребоваться включить данных заголовочные файлы.

Операции IPC_INFO, SEM_STAT и SEM_INFO используются программой ipcs(1) для
получения информации о выделенных ресурсах. В будущем для этого может быть
задействован интерфейс файловой системы /proc.

В Linux 2.2 различные поля struct semid_ds имели тип short. В Linux 2.4 тип был
изменён на long. Для задействования преимуществ этого изменения необходима
перекомпиляция программы с glibc-2.1.91 или более поздней версией (ядро различает
старые и новые вызовы по флагу IPC_64 в аргументе cmd).

В некоторых ранних версиях glibc объединение semun определялось в <sys/sem.h>, но
в POSIX.1 требовалось, чтобы это объединение определял вызывающий. В версиях
glibc, в которых это объединение не определено, в <sys/sem.h> определён макрос
_SEM_SEMUN_UNDEFINED.

На работу наборов семафоров и вызова semctl() влияет системное ограничение:

SEMVMX Максимальное значение semval: зависит от реализации (32767).

Для лучшей переносимости программ желательно всегда вызывать semctl() c четырьмя
аргументам.

Значение sempid
В POSIX.1 значение sempid определено как «ID процесса последней операции» над
семафором, и явно отмечено, что это значение устанавливается успешным вызовом
semop(2), подразумевая, что больше никто не изменяет sempid.

Одни реализации следуют требованиям, указанным в POSIX.1, а другие нет (вина
здесь, вероятно, лежит на POSIX.1, так как ему не удастся охватить поведение всех
существующих реализаций). Также, разные реализации обновляют sempid другими
операциями, обновляющими значение семафора: SETVAL и SETALL, а также изменение
семафора, выполняемое при завершении процесса как следствие использования флага
SEM_UNDO (смотрите semop(2)).

Linux также обновляет sempid при операциях SETVAL и регулировки семафора. Однако,
непоследовательно, ранние версии Linux по 4.5 включительно не обновляли sempid при
операциях SETALL. Это было исправлено в Linux 4.6.



СМОТРИТЕ ТАКЖЕ


Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 446 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar