ОБЗОР
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
ОПИСАНИЕ
Системный вызов semget() возвращает идентификатор набора семафоров System V, связанный с аргументом key. Если значение key равно IPC_PRIVATE или с ключом key не связано ни одного существующего набора семафора, а в semflg задано IPC_CREAT, создаётся новый набор из nsems семафоров.Если в semflg одновременно указаны IPC_CREAT и IPC_EXCL и набор семафоров для key уже существует, то semget() завершается с ошибкой и errno присваивается значение EEXIST (такой же результат как с O_CREAT | O_EXCL у open(2)).
При создании в 9 начальных битах аргумента semflg указываются права (владелец, группа и др.) на набор семафоров. Формат значения битов совпадает с аргументом mode вызова open(2) (но права на выполнение для семафоров ничего не означают, а права на запись означают право изменять значения семафоров).
При создании нового набора семафоров semget() инициализирует связанную с семафором структуру данных semid_ds (см. semctl(2)) следующим образом:
- Полям sem_perm.cuid и sem_perm.uid присваиваются значения эффективного идентификатора пользователя вызывающего процесса.
- Полям sem_perm.cgid и sem_perm.gid присваиваются значения эффективного идентификатора группы вызывающего процесса.
- Младшим 9 битам sem_perm.mode присваивается значение младших 9 бит semflg.
- Полю sem_nsems присваивается значение nsems.
- Полю sem_otime присваивается значение 0.
- Полю sem_ctime присваивается значение текущего времени.
Если набор семафоров не создаётся, то аргумент nsems может быть равен 0 (не учитывать). Иначе аргумент nsems должен быть больше 0 и меньше или равен максимальному количеству семафоров в наборе (SEMMSL).
Если набор семафоров уже существует, то проверяются права доступа.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается идентификатор набора семафоров (неотрицательное целое), иначе возвращается -1, а переменной errno присваивается номер ошибки.ОШИБКИ
При ошибке errno присваиваются следующие значения:- EACCES
- Набор семафоров для ключа key существует, но вызывающий процесс не имеет прав доступа к нему и не имеет мандата CAP_IPC_OWNER.
- EEXIST
- В semflg указаны IPC_CREAT и IPC_EXCL, но набор семафоров уже существует для key.
- EINVAL
- Значение nsems меньше 0 или больше максимально возможного для набора количества семафоров (SEMMSL).
- EINVAL
- Набор семафоров, соответствующий key, уже существует, но nsems больше, чем количество семафоров в этом наборе.
- ENOENT
- Для ключа key не существует набора семафоров и в semflg нет флага IPC_CREAT.
- ENOMEM
- Набор семафоров должен быть создан, но в системе не хватает памяти для хранения новой структуры данных.
- ENOSPC
- Набор семафоров должен быть создан, но при этом будет превышен системный лимит на количество наборов семафоров (SEMMNI) или системный лимит на количество семафоров (SEMMNS).
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, POSIX.1-2001.ЗАМЕЧАНИЯ
Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.Значение IPC_PRIVATE не поле флага, а тип key_t. Если key равно этому специальному значению, то системный вызов игнорирует всё кроме 9-ти младших битов semflg и создаёт новый набор семафоров (при успешном выполнении).
Инициализация семафоров
Значения только что созданных семафоров не определены (в POSIX.1-2001 и POSIX.1-2008 это указано явно, хотя в POSIX.1-2008 сказано, что в будущих версиях стандарта от реализации может потребоваться инициализировать семафоры 0). Хотя Linux, подобно многим другим реализациям, инициализирует семафоры значением 0, переносимое приложение не может полагаться на это: оно должно явно инициализировать семафоры нужным значением.Инициализацию можно выполнять с помощью semctl(2) с операцией SETVAL или SETALL. При наличии нескольких абонентов неизвестно, кто первый выполнит инициализацию, и чтобы избежать состязательности нужно проверять sem_otime на ненулевое значение в связанной структуре данных, получаемой с помощью semctl(2) и операции IPC_STAT.
Ограничения семафоров
Ниже приведены ограничения на ресурсы набора семафоров, оказывающие влияние на вызов semget():- SEMMNI
- Ограничение на максимальное количество наборов семафоров. В системах Linux до версии 3.19, значением по умолчанию этого ограничения было 128. Начиная с Linux 3.19, значение по умолчанию равно 32000. В Linux это ограничение можно получать и изменять через четвёртое поле /proc/sys/kernel/sem).
- SEMMSL
- Максимальное количество семафоров на один ID семафора. В системах Linux до версии 3.19, значением по умолчанию этого ограничения было 250. Начиная с Linux 3.19, значение по умолчанию равно 32000. В Linux это ограничение можно получать и изменять через первое поле /proc/sys/kernel/sem).
- SEMMNS
- Ограничение на максимальное количество семафоров в системе: зависит от политики (в Linux это ограничение можно получать и изменять через второе поле /proc/sys/kernel/sem). Заметим, что количество семафоров в системе также ограничено произведением SEMMSL и SEMMNI.