Семафоры являются одним из классических примитивов синхронизации. Значение семафора - это целое число в диапазоне от 0 до 32767. Поскольку во многих приложениях требуется использование более одного семафора, ОС Linux предоставляет возможность создавать множества семафоров. Их максимальный размер ограничен системным параметром SEMMSL. Множества семафоров создаются при помощи системного вызова semget.
Процесс, выполнивший системный вызов semget, становится владельцем
или создателем множества семафоров. Он определяет,
сколько будет семафоров
в множестве; кроме того, он специфицирует первоначальные права на
выполнение операций над множеством для всех процессов, включая себя.
Впоследствии данный процесс может уступить право собственности или
изменить права на операции при помощи системного вызова semctl, предназначенного
для управления семафорами, однако на протяжении всего времени существования
множества семафоров создатель остается создателем. Другие процессы,
обладающие соответствующими правами, для выполнения прочих управляющих
действий также могут использовать системный вызов semctl.
Над каждым семафором, принадлежащим некоторому множеству, при помощи системного вызова semop можно выполнить любую из трех операций:
Операции могут снабжаться флагами. Флаг SEM_UNDO означает, что операция выполняется в проверочном режиме, т. е. требуется только узнать, можно ли успешно выполнить данную операцию.
При отсутствии флага IPC_NOWAIT системный вызов semop должен быть приостановлен до тех пор, пока значение семафора благодаря действиям другого процесса, не позволит успешно завершить операцию (ликвидация множества семафоров также приведет к завершению системного вызова). Подобные операции называются ''операциями с блокировкой''. С другой стороны, если обработка завершается неудачей и не указано, что выполнение процесса должно быть приостановлено, операция над семафором называется ``операцией без блокировки''.
Системный вызов semop оперирует не с отдельным семафором, а со множеством семафоров, применяя к нему ``массив операций''. Массив содержит информацию о том, с какими семафорами нужно оперировать и каким образом. Выполнение массива операций с точки зрения пользовательского процесса является неделимым действием. Это значит, во-первых, что если операции выполняются, то только все вместе и, во-вторых, что другой процесс не может получить доступа к промежуточному состоянию множества семафоров, когда часть операций из массива уже выполнена, а другая часть еще не начиналась.
Операционная система выполняет операции из массива по очереди, причем порядок не оговаривается. Если очередная операция не может быть выполнена, то эффект предыдущих операций аннулируется. Если таковой оказалась операция с блокировкой, выполнение системного вызова приостанавливается. Если неудачу потерпела операция без блокировки, системный вызов немедленно завершается, возвращая значение -1 как признак ошибки, а внешней переменной errno присваивается код ошибки.