semget(2)
| SEMGET(2) | Руководство программиста Linux | SEMGET(2) |
ИМЯ
semget - считывает идентификатор набора семафоров System V
ОБЗОР
#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. Его можно использовать для получения идентификатора уже созданного набора семафоров (если semflg равно нулю и значение key не равно IPC_PRIVATE) или для создания нового.
Новый набор семафоров nsems создаётся, если значение key равно IPC_PRIVATE или с ключом key не связано ни одного существующего набора семафоров, а в semflg задано IPC_CREAT.
Если в 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 в пространстве имён пользователя, который управляет его пространством имён IPC.
- 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.
ДЕФЕКТЫ
Имя IPC_PRIVATE, возможно, было выбрано неудачно, IPC_NEW отражает смысл действия более ясно.
СМОТРИТЕ ТАКЖЕ
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), sysvipc(7)
| 2019-08-02 | Linux |
