|
Программирование >> Структура ядра и системные вызовы
когда процесс Y готов позволить процессу X возобновить выполнение, он увеличивает значения семафоров до величин, достаточных для успешного выполнения операции над семафором, осуществляемой процессом X. Ядро разблокирует процесс X. Если значение семафора - положительное целое, то процесс, явно запрашивающий нулевое значение, блокируется до тех пор, пока другой процесс не уменьшит значение этого семафора до нуля. Процесс, имеющий доступ к набору семафоров, может выполнять операции над отдельными семафорами или одновременно оперировать дву\1я и более семафорами. В последнем случае действует следующее правило: если какая-либо операция не может быть выполнена над любым из выбранных семафоров, то неудачной считается операция по отношению к обоим семафорам и их значения остаются без изменений. Это сделано для того, чтобы в случае, если два или более процессов попытаются прочитать и записать значения одного и того же набора семафоров, операции мог выполнить только один процесс. 10.5.1. Поддержка семафоров ядром UNIX В ос UNIX System V.3 и V.4 в адресном пространстве ядра имеется таблица семафоров, в которой отслеживаются все создаваемые в системе наборы семафоров. В каждом элементе таблицы семафоров находятся следующие данные об одном наборе семафоров: Имя, представляющее собой целочисленный идентификационный ключ, присвоенный набору семафоров процессом, который его создал. Другие процессы могут, указывая этот ключ, открывать набор и получать дескриптор для доступа к набору. UID создателя набора семафоров и идентификатор его группы. Процесс, эффективный UID которого совпадает с UID создателя, может удалять набор и изменять параметры управления им. UID назначенного владельца и идентификатор его группы. Эти идентификаторы обычно совпадают с идентификаторами создателя, но процесс создателя может устанавливать эти идентификаторы для переназначения владельца набора и принадлежности к группе. Права доступа к набору для чтения-записи по категориям владелец , группа и прочие . Процесс, имеющий право на чтение набора, может запрашивать значения семафоров и UID назначенного владельца и группы. Процесс, имеющий право на запись в набор, может изменять значения семафоров. Количество семафоров в наборе. Время изменения одного или нескольких значений семафоров последним процессом. Время последнего изменения управляющих параметров набора каким-либо процессом. Указатель на массив семафоров. Семафоры в наборе обозначаются индексами массива: например, первый семафор в наборе имеет индекс нуль, второй - единицу и т.д. В каждом семафоре содержатся следующие данные: значение семафора; идентификатор процесса, который оперировал семафором в последний раз; число процессов, заблокированных в текущий момент и ожидающих увеличения значения семафора; число процессов, заблокированных в текущий момент и ожидающих обращения значения семафора в нуль. На рис. 10.3 изображена структура данных ядра, используемая для манипулирования семафорами.
Рис. 10.3. Структура данных ядра, используемая для манипулирования семафорами Как и сообщения, семафоры хранятся в адресном пространстве ядра и являются устойчивыми, т.е. сохраняются независимо от завершения создавшего их процесса. У каждого набора семафоров есть назначенный владелец, и удалить набор или изменить его управляющие параметры могут только процессы, имеющие права привилегированного пользователя, создателя набора или назначенного владельца. Если набор семафоров удаляется, то ядро активизирует все процессы, которые в данный момент заблокированы семафорами этого набора; все произведенные данными процессами системные вызовы прерываются и возвращают код неудачного завершения, -I. Система устанавливает ряд ограничений на манипулирование семафорами. Они определяются в заголовке <sys/sem.h>; Системное ограничение Значение 1SEMMNI SEMMNS SEMMSL SEMOPM Максимальное число наборов семафоров, которые могут существовать в системе в любой данный момент времени Максимальное число семафоров во всех наборах, которые могут существовать в системе в любой данный момент времени , Максимально допустимое число семафоров в одном наборе Максимальное число семафоров в наборе, над которыми могут одновременно выполняться операции в любой данный момент времени Влияние этих системных ограничений на процессы таково: если попытка процесса создать новый набор семафоров вызовет превышение лимита SEMMNI или SEMMNS, этот процесс будет заблокирован до тех пор, пока какой-либо процесс не удалит один или несколько существующих наборов; если процесс попытается создать набор более чем из SEMMSL семафоров, этот системный вызов выполнен не будет; если процесс попытается одновременно выполнить операцию более чем над SEMOPM семафорами в наборе, этот системный вызов выполнен не будет. 10.5.2. API ОС UNIX для семафоров в заголовке <sys/ipc.h> объявляются тип данных struct ipc perin, который используется в данном наборе семафоров для хранения UID, GID, ID создателя и его группы, идентификатор и права доступа на чтение и запись. Элементы таблицы семафоров имеют тип данных struct semidjds, который определяется в заголовке <sys/sem.h>. Ниже перечислены названия полей этой структуры и данные, которые в них хранятся. Поле Данные
Помимо этого, тип данных struct sem, определенный в заголовке <sys/sem.h>, используется для представления данных, хранящихся в семафоре. Поле Данные ( V V semval Целочисленное значение текущего семафора sempid Идентификатор процесса, который выполнял операции над данным семафором в последний раз semncnt Число процессов, которые заблокированы и ожидают увеличения значения семафора semzcnt Число процессов, которые заблокированы и ожидают обращения значения семафора в нуль На рис. 10.4 показано, как вышеупомянутые структуры используются в таблице семафоров и в записях значений семафоров. struct semid ds
Таблица семафоров Рис. 10.4. Типы данных таблицы семафоров и записи значений семафора в ОС UNIX System V имеются три API, предназначенные для манипулирования семафорами. АР! семафоров Назначение semget semop semcti Открытие и создание (при необходимости) набора семафоров Запрос и изменение значения семафора Запрос и изменение управляющих параметров набора семафоров, удаление набора Для этих API необходимы следующие файлы заголовков: ♦include <sys/types.h> ♦include <sys/ipc.h> ♦include <sys/sem.h> 10.5.3. Функция semget Прототип функции semget имеет следующий вид: #include <sys/types.h> #include <sys/ipc.h> #include <sys/setn.h> int semget (key t key, int num sem, int flag ); Эта функция открьгеает набор семафоров, идентификатор которого задан значением аргумента key, и возвращает неотрицательный целочисленный дескриптор. Его можно использовать в других API семафоров для запроса и изменения значения семафора, а также для запроса и/или установки управляющих параметров набора семафоров. Если значение аргумента key - положительное целое, рассматриваемый API пробует открыть набор семафоров, ключевой идентификатор которого совпадает с указанным значением. Если же значением key является макрос IPC PRIVATE, API создает новый набор семафоров, который будет использоваться исключительно вызывающим процессом. Такие частные семафоры обычно выделяются родительским процессом, создающим затем один или несколько порожденных процессов. Родительский и порожденные процессы пользуются этими семафорами для синхронизации своей работы. При нулевом значении аргумента flag API прерывает свою работу, если отсутствует набор семафоров, ключевой идентификатор которого совпадал бы с заданным значением key; в противном случае возвращается дескриптор этого набора. Если процессу необходимо создать новый набор с идентификатором key (и набора с таким идентификатором нет), то значение аргумента flag должно представлять собой результат побитового логического сложения константы IPC CREAT и числовых значений прав доступа к новому набору для чтения и записи. Значение num sem может быть равно нулю, если флаг IPC CREAT в аргументе flag не указан, или числу семафоров во вновь создаваемом наборе. Например, следующий системный вызов создает двухсемафорный набор с идентификатором 15 и разрещением на чтение-запись для владельца, только на чтение для членов группы и прочих пользователей, если такого набора еще нет. Этот вызов возвращает целочисленный дескриптор, необходимый для последующих обращений к данному набору: int perms = S IRUSR I S IWUSR I S IRGRP 1 S IROTH; int semfdesc = semget(15, 2, IRC CREAT perms); Для гарантированного создания нового набора семафоров можно указать одновременно с флагом IPC CREAT флаг IPC EXCL. Тогда API будет успещно выполнен только в том случае, если он создаст новый набор с заданным значением key. В случае неудачи этот API возвращает -1. 10.5.4. Функция semop Прототип функции semap имеет следующий вид: #inciude <sys/types.h> #include <sys/ipc.h> #include <sys/setn.h> int semop (int semfd, struct sembuf* opPtr, int len ); С помощью этого API можно изменять значение одного или нескольких семафоров в наборе (указанном аргументом semfd) и/или проверять равенство их значений нулю. Аргумент opPtr - это указатель на массив объектов типа struct sembuf, каждый из которых задает одну операцию (запрос или изменение значения). Аргумент len показывает, сколько элементов имеется в массиве, указанном аргументом opPtr. Тип данных struct sembuf определяется в заголовке <sys/sem.h>: struct sembuf { short sem num; short sem op; short sem flg; индекс семафора операция над семафором флаг(и) операции Переменная sem op может иметь следующие значения. Значение sem op Смысл Положительное число Отрицательное число Увеличить значение указанного семафора на эту величину Уменьшить значение указанного семафора на эту величину Проверить равенство значения семафора нулю Если вызов semop попытается уменьшить значение семафора до отрицательного числа или посчитает, что значение семафора равно нулю, когда на самом деле это не так, то ядро заблокирует вызывающий процесс. Этого не произойдет в том случае, если в полях sem Jig элементов массива, где sem op меньше или равно нулю, указан флаг IPC NOWAIT. В полях sem Jig объектов struct sembuf может быть установлен еще один флаг - SEM UNDO. Этот флаг дает ядру указание отслеживать изменение значения семафора (произведенное вызовом semop). При завершении вызывающего процесса ядро ликвидирует сделанные изменения, чтобы процессы, ожидающие изменения семафоров, не были заблокированы навечно, что может произойти в том случае, если вызывающий процесс забудет отменить сделанные им изменения.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |