Московский физико-технический институт
Опубликован: 16.09.2004 | Доступ: свободный | Студентов: 7345 / 1504 | Оценка: 4.44 / 4.28 | Длительность: 15:33:00
Лекция 5:

Семафоры в UNIX как средство синхронизации процессов

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

Удаление набора семафоров из системы с помощью команды ipcrm или системного вызова semctl()

Как мы видели в примерах, массив семафоров может продолжать существовать в системе и после завершения использовавших его процессов, а семафоры будут сохранять свое значение. Это может привести к некорректному поведению программ, предполагающих, что семафоры были только что созданы и, следовательно, имеют нулевое значение. Необходимо удалять семафоры из системы перед запуском таких программ или перед их завершением. Для удаления семафоров можно воспользоваться командами ipcs и ipcrm, рассмотренными в материалах предыдущего семинара. Команда ipcrm в этом случае должна иметь вид

ipcrm sem <IPC идентификатор>

Для этой же цели мы можем применять системный вызов semctl() , который умеет выполнять и другие операции над массивом семафоров, но их рассмотрение выходит за рамки нашего курса.

Системный вызов semctl()

Прототип системного вызова

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, 
           union semun arg);

Описание системного вызова

Системный вызов semctl предназначен для получения информации о массиве IPC семафоров, изменения его атрибутов и удаления его из системы. Данное описание не является полным описанием системного вызова, а ограничивается рамками текущего курса. Для изучения полного описания обращайтесь к UNIX Manual.

В нашем курсе мы будем применять системный вызов semctl только для удаления массива семафоров из системы. Параметр semid является дескриптором System V IPC для массива семафоров, т. е. значением, которое вернул системный вызов semget() при создании массива или при его поиске по ключу.

В качестве параметра cmd в рамках нашего курса мы всегда будем передавать значение IPC_RMID – команду для удаления сегмента разделяемой памяти с заданным идентификатором. Параметры semnum и arg для этой команды не используются, поэтому мы всегда будем подставлять вместо них значение 0.

Если какие-либо процессы находились в состоянии ожидание для семафоров из удаляемого массива при выполнении системного вызова semop() , то они будут разблокированы и вернутся из вызова semop() с индикацией ошибки.

Возвращаемое значение

Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

Написание, компиляция и прогон программы с организацией взаимоисключения с помощью семафоров для двух процессов, взаимодействующих через разделяемую память

В материалах семинаров 6–7 было показано, что любые неатомарные операции, связанные с изменением содержимого разделяемой памяти, представляют собой критическую секцию процесса или нити исполнения. Модифицируйте программы из раздела "Необходимость синхронизации процессов и нитей исполнения, использующих общую память" семинаров 6–7, которые иллюстрировали некорректную работу через разделяемую память, обеспечив с помощью семафоров взаимоисключения для их правильной работы.

Написание, компиляция и прогон программы с организацией взаимной очередности с помощью семафоров для двух процессов, взаимодействующих через pipe

В материалах семинара 5, когда речь шла о связи родственных процессов через pipe, отмечалось, что pipe является однонаправленным каналом связи, и что для организации связи через один pipe в двух направлениях необходимо использовать механизмы взаимной синхронизации процессов. Организуйте двустороннюю поочередную связь процесса-родителя и процесса-ребенка через pipe, используя для синхронизации семафоры, модифицировав программу из раздела "Прогон программы для организации однонаправленной связи между родственными процессами через pipe" семинара 5.

Понятие о POSIX-семафорах

В стандарте POSIX вводятся другие семафоры, полностью аналогичные семафорам Дейкстры. Для инициализации значения таких семафоров применяется функция sem_init(), аналогом операции P служит функция sem_wait(), а аналогом операции Vфункция sem_post(). К сожалению, в Linux такие семафоры реализованы только для нитей исполнения одного процесса, и поэтому подробно мы на них останавливаться не будем.

< Лекция 4 || Лекция 5: 123 || Лекция 6 >