SEMGET(2)

ИМЯ
semget - считывает идентификатор набора семафоров

ОБЗОР
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);

ОПИСАНИЕ
Системный вызов semget() возвращает идентификатор набора семафоров, связанный с аргументом 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) (но права на выполнение для семафоров ничего не означают, а права на запись означают право изменять значения семафоров).

После создания значения семафоров не определено (в соответствии с POSIX.1-2001). Но в Linux, как и многих других реализациях, значения семафоров инициализируются 0, переносимые приложения не могут полагаться на это: они должны явно присваивать семафорам желаемое начальное значение.

При создании нового набора семафоров 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
    Набор семафоров для ключа key существует, но в semflg заданы флаги IPC_CREAT и IPC_EXCL.

EINVAL
    Значение nsems меньше 0 или больше максимально возможного для набора количества семафоров (SEMMSL), или набор семафоров, соответствующий 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 и создаёт новый набор семафоров (при успешном выполнении).

Ниже приведены ограничения на ресурсы набора семафоров, оказывающие влияние на вызов semget():

SEMMNI
    Максимальное количество наборов семафоров в системе: зависит от политики (в Linux это ограничение можно получать и изменять через четвёртое поле /proc/sys/kernel/sem).

SEMMSL
    Максимальное количество семафоров в semid: зависит от реализации (в Linux это ограничение можно получать и изменять через первое поле /proc/sys/kernel/sem).

SEMMNS
    Максимальное количество семафоров в системе: зависит от политики (в Linux это ограничение можно получать и изменять через второе поле /proc/sys/kernel/sem). Значения больше чем SEMMSL * SEMMNI считаются некорректными.

ДЕФЕКТЫ
Имя IPC_PRIVATE, возможно, было выбрано неудачно, IPC_NEW отражает смысл действия более ясно.

Семафоры в наборе не инициализируются вызовом semget(). Для того, чтобы их инициализировать, нужно использовать вызов semctl(2), чтобы выполнить операцию SETVAL или SETALL над набором семафоров (если не понятно какой семафор нужно иницилизировать первым, для предотвращения состязательности проверяется ненулевое значение sem_otime в связанной структуре данных, получаемой с помощью вызова semctl(2) с операцией IPC_STAT).

СМОТРИТЕ ТАКЖЕ
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), svipc(7)