Первый параметр sem_id
semget. Второй параметр sem_ops — указатель на массив структур, у каждой из которых есть, по крайней мере, следующие элементы:struct sembuf {
short sem_num;
short sem_op;
short sem_flg;
}
Первый параметр sem_num
sem_op — значение, на которое должен изменяться семафор. (Вы можете увеличивать и уменьшать семафор на значения, не равные 1.) Как правило, применяются только два значения: -1 для операции P, заставляющей ждать, пока семафор не станет доступен, и +1 для операции V, оповещающей о том, что в данный момент семафор доступен.Последний элемент sem_flg
SEM_UNDO. Это значение заставляет операционную систему отслеживать изменения значения семафора, сделанные текущим процессом, и, если процесс завершается, не освободив семафор, позволяет операционной системе автоматически освободить семафор, если он удерживался этим процессом. Хорошо взять за правило установку sem_flg, равным SEM_UNDO, если вам не требуется иного поведения. Если же вы все-таки решили, что вам нужно значение, отличное от SEM_UNDO, очень важно быть последовательным, иначе вы можете оказаться в замешательстве относительно попыток ядра системы "убрать" ваши семафоры, когда ваш процесс завершается.Все действия, предусмотренные semop
semop можно найти на страницах интерактивного справочного руководства.Функция semctl
int semctl (int sem_id, int sem_num, int command, ...);
Первый параметр sem_id — идентификатор семафора, полученный от функции semget
sem_num — номер семафора. Он применяется при работе с массивом семафоров. Обычно этот параметр равен 0, первый и единственный семафор. Параметр command — предпринимаемое действие, и четвертый параметр, если присутствует, — union (объединение) типа semun, которое в соответствии со стандартом X/Open должно содержать как минимум следующие элементы:union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
}
В большинстве версий ОС Linux определение объединения semun
semctl. Если вы найдете его, мы полагаем, что вы примените определение из вашего справочного руководства, даже если оно отличается от приведенного на страницах этой книги.Существует множество разных значений параметра command, допустимых в функции semctl
semctl см. в интерактивном справочном руководстве.Два часто используемых значения command
□ SETVAL
val объединения semun. Такое действие необходимо для того, чтобы увеличить значение семафора перед первым его применением;□ IPC_RMID
Функция semctl
command. Если значение команды — IPC_RMID, функция в случае успешного завершения вернет 0 и -1 в противном случае.Применение семафоров
Как видно из содержания предыдущих разделов, операции с семафорами могут быть очень сложными. Это не самое печальное, потому что программирование многих процессов или потоков с критическими секциями — очень трудная задача сама по себе, и наличие сложного программного интерфейса лишь увеличивает интеллектуальную нагрузку.
К счастью, большинство задач, нуждающихся в семафорах, можно решить, применяя единственный бинарный семафор — простейший тип семафора. В следующем примере (упражнение 14.1) вы используете полный программный интерфейс для создания очень простого интерфейса типа Р и V для бинарного семафора. Затем вы примените этот простенький интерфейс для демонстрации того, как функционируют семафоры.
В экспериментах с семафорами будет использоваться единственная программа sem1.с, которую вы сможете запускать несколько раз. Необязательный параметр будет применяться для того, чтобы показать, отвечает ли программа за создание и уничтожение семафора.