Шрифт:
Значение конкретного семафора из набора хранится во внутренней структуре
ushort semval | Значение семафора |
pid_t sempid | Идентификатор процесса, выполнившего последнюю операцию над семафором |
ushort semncnt | Число процессов, ожидающих увеличения значения семафора |
ushort semzcnt | Число процессов, ожидающих обнуления семафора |
Помимо собственно значения семафора, в структуре sem хранится идентификатор процесса, вызвавшего последнюю операцию над семафором, число процессов, ожидающих увеличения значения семафора, и число процессов, ожидающих, когда значение семафора станет равным нулю. Эта информация позволяет ядру производить операции над семафорами, которые мы обсудим несколько позже.
Для получения доступа к семафору (и для его создания, если он не существует) используется системный вызов semop(2):
В случае успешного завершения операции функция возвращает дескриптор объекта, в случае неудачи - -1. Аргумент
После получения дескриптора объекта процесс может производить операции над семафором, подобно тому, как после получения файлового дескриптора процесс может читать и записывать данные в файл. Для этого используется системный вызов semop(2):
В качестве второго аргумента функции передается указатель на структуру данных, определяющую операции, которые требуется произвести над семафором с дескриптором
Каждый элемент набора операций
UNIX допускает три возможные операции над семафором, определяемые полем
1. Если величина
2. Если значение
3. Если величина
Можно заметить, что первая операция изменяет значение семафора (безусловное выполнение), вторая операция только проверяет его значение (условное выполнение), а третья — проверяет, а затем изменяет значение семафора (условное выполнение).
При работе с семафорами взаимодействующие процессы должны договориться об их использовании и кооперативно проводить операции над семафорами. Операционная система не накладывает ограничений на использование семафоров. В частности, процессы вольны решать, какое значение семафора является разрешающим, на какую величину изменяется значение семафора и т.п.
Таким образом, при работе с семафорами процессы используют различные комбинации из трех операций, определенных системой, по-своему трактуя значения семафоров.
В качестве примера рассмотрим два случая использования бинарного семафора (т.е. значения которого могут принимать только 0 и 1). В первом примере значение 0 является разрешающим, а 1 запирает некоторый разделяемый ресурс (файл, разделяемая память и т.п.), ассоциированный с семафором. Определим операции, запирающие ресурс и освобождающие его: