|
Программирование >> Структура ядра и системные вызовы
памяти, создаваемые в системе. В каждом элементе таблицы находятся следующие данные об одной разделяемой области памяти: Имя, представляющее собой целочисленный идентификационный ключ, присвоенный разделяемой области памяти процессом, который ее создал, j Другие процессы могут, указывая этот ключ, открывать данную облас и получать дескриптор для дальнейшего обращения к области и отсоеди нения от нее. UID создателя разделяемой области памяти и идентификатор его фуппы. Процесс, эффективный UID которого совпадает с UID создателя разделяемой области памяти, может удалять область и изменять параметры управления ею. UID назначенного пользователя-владельца и идентификатор его группы. Эти идентификаторы обычно совпадают с идентификаторами создателя, но создатель может устанавливать эти идентификаторы для переназначения владельца области и принадлежности к группе. Права доступа к области для чтения-записи по категориям владелец , группа и прочие . Процесс, имеющий право на чтение из данной области, может читать из нее данные и запрашивать UID назначенного пользователя и его группы. Процесс, имеющий разрешение на запись в область, может записывать в нее данные. Размер разделяемой области памяти в байтах. Время, когда какой-либо процесс в последний раз подсоединялся к области. Время, когда какой-либо процесс в последний раз отсоединялся от области. Время, когда какой-либо процесс в последний раз изменил управляющие параметры области. На рис. 10.5 изображена структура данных ядра, предназначенная для манипулирования разделяемой памятью. Разделяемая область памяти. Таблица разделяемой памяти Таблица процессов Рис. 10.5. Структура данных ядра для манипулирования разделяемой памятью Аналогично сообщениям и семафорам, разделяемая память располагается в адресном пространстве ядра, и разделяемые области не освобождаются, даже если создавшие их процессы завершаются. У каждой разделяемой области памяти есть назначенный владелец, и удалять эту область или корректировать ее управляющие параметры могут только процессы с права-ми привилегированного пользователя, создателя или назначенного владель-la. Для манипулирования разделяемой памятью система устанавливает ряд )фаничений. Они определяются в заголовке <sys/shm.h>:
Влияние этих системных ограничений на процессы таково: если попытка процесса создать новую разделяемую область памяти вызовет превышение лимита SHMMNI, этот процесс будет блокироваться до тех пор, пока другой процесс не удалит одну из существующих областей; если процесс попытается создать область с размером меньше SHMMIN или больше SHMMAX, этот системный вызов выполнен не будет. 10.7.2. API ОС UNIX для разделяемой памяти В заголовке <sys/ipc.h> объявляется тип данных struct ipc perm, используемый для хранения UID создателя, UID владельца, идентификаторов их групп, присвоенного ключевого имени и прав на чтение и запись, установленных для разделяемой области памяти. Элементы таблицы разделяемой памяти относятся к типу данных struct shmid ds, который определяется в заголовке <sys/shm.h>. Ниже перечислены информационные поля этой структуры и данные, которые в них хранятся. Поле Данные shm perm Данные, хранящиеся в записи struct ipcjperm shm segsz Размер разделяемой области памяти в байтах shm pid Идентификатор процесса, который в последний раз подсоединялся к области shm cpid Идентификатор процесса-создателя shm nattch Число процессов, подсоединенных к области в данный момент shm atime Время, когда процесс в последний раз подсоединялся к области shm dtime Время, когда процесс в последний раз отсоединялся от области shm ctime Время, когда последний процесс изменил управляющие параметры области Для манипулирования разделяемой областью памяти в UNIX System V/ имеются четыре API: API разделяемой памяти Назначение shmget Создание и открытие разделяемой области памяти shmat Подсоединение разделяемой области памяти к вир- туальному адресному пространству процесса с тем, чтобы этот процесс мог читать данные из разделяемой памяти и/или записывать в нее данные shmdt shmcti Отсоединение разделяемой области памяти от виртуального адресного пространства процесса Запрос и изменение управляющих параметров разделяемой области памяти, а также ее удаление Для перечисленных в таблице API разделяемой памяти необходимы следующие файлы заголовков: ♦include <sys/types.h> tinclude <sys/ipc.h> finclude <sys/shm.h> 10.7.3. Функция shmget Прототип функции shmget имеет следующий ввд: #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmget (key t key, Int size, int flag ); Этот API открывает разделяемую область памяти, идентификатор которой совпадает со значением аргумента key, и возвращает неотрицательный целочисленный дескриптор. Его можно использовать в других API разделяемой памяти. Если значение аргумента key - положительное целое, данный API пробует открыть разделяемую область памяти, ключевой идентификатор которой совпадает с этим значением. Если же значением key является макрос IPCPRIVATE, API выделяет новую разделяемую область памяти, которая будет использоваться исключительно вызываюидам процессом. Такая частная разделяемая область памяти обычно выделяется родительским процессом. который затем создает один или несколько порожденных процессов. Родительский и порожденные процессы пользуются этой разделяемой памятью ; для обмена данными. Аргумент size задает размер области разделяемой памяти, которая может эыть подсоединена к вызывающему процессу с помощью API shmat. Если в Результате этого вызова создается новая область разделяемой памяти, ее змер будет определяться аргументом size. В случае, когда вызов открывает уке существующую область, значение аргумента size может быть меньше размера выделенной области разделяемой памяти или равно ему. Если в последнем случае значение size меньше фактического размера области разделяемой памяти, то вызывающий процесс может получить доступ только к первым size байтам области разделяемой памяти. Если аргумент flag равен нулю и нет области разделяемой памяти, идентификатор которой совпадал бы с заданным значением key, то этот API завершается неудачно. В противном случае он возвращает дескриптор этой области. Если процессу необходимо создать разделяемую область памяти с заданным key (и области с таким идентификатором нет), то значение аргумента flag должно представлять собой результат побитового логического сложения константы IPCCREAT и прав доступа к новой области памяти для чтения и записи. В случае успешного выполнения эта функция возвращает положительный дескриптор, а в случае неудачи -1. 10.7.4. Функция shmat h -iz Прототип функции shmat выглядит следующим образом: #include <sys/types.h:?r #include <sys/ipc.h> щ-#include <sys/shm.h>ri void* shmat ( int shmid, void* addr, int flag ); Эта функция подсоединяет область разделяемой памяти, указанную аргументом shmid, к виртуальному адресному пространству вызывающего процесса. Процесс может затем читать данные из указанной области памяти и записывать в нее данные. Если это вновь создаваемая область разделяемой памяти, то ядро реально выделяет область памяти только тогда, когда первый процесс вызывает рассматриваемую функцию для подсоединения к новой области. Аргумент addr задает начальный виртуальный адрес адресного пространства вызывающего процесса, в которое необходимо отобразить разделяемую память. Если это значение равно нулю, ядро может само найти в вызывающем процессе подходящий виртуальный адрес для отображения разделяемой памяти. Большинство приложений должны устанавливать значение addr в нуль, если они явно не хранят в разделяемой области памяти ссылки на указатели или адреса (например, не держат в этой области связный список). Очень важно, чтобы каждый процесс, обращающийся к данной области памяти, указывал один и тот же начальный виртуальный адрес области, в которую отображена разделяемая память. Если значение аргумента addr не равно нулю, аргумент flag мож содержать флаг SHM RND. Этот флаг указывает ядру на то, что виртуальны адрес, заданный в аргументе addr, можно округлить до границы страни памяти. Если флаг SHM RND отсутствует и значение аргумента addr равно нулю, соответствующий API завершается неудачно (это означает, ядро не может отобразить разделяемую память в область, заданную ви альным адресом). Аргумент flag может иметь также значение SHM RD0NLY, которое говорит о том, что вызывающий процесс подсоединяется к разделяемой памяти только для чтения. Если этот флаг не установлен, то по умолчанию процесс может читать и записывать данные в разделяемую память с учетом разрешений, установленных создателем данной области. Этот API возвращает виртуальный адрес области отображения разделяемой памяти, а в случае неудачи--1. Следует отметить, что любой процесс, с целью подсоединения одной разделяемой области памяти к виртуальным адресным пространствам многих процессов, может вызывать функцию shmat многократно. 10.7.5. Функция shmdt Прототип функции shmdt имеет следующий вид: #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmdt ( void* addr); Эта функция отсоединяет разделяемую память от заданного аргументом addr виртуального адреса вызывающего процесса. Прежде чем вызывать данную функцию, необходимо получить посредством вызова shmat значение addr. В случае успешного выполнения рассматриваемая функция возвращает О, а в случае неудачи--1. Приведенная ниже программа /е5/ 5А г. С открывает разделяемую область памяти размером 1024 байта с ключевым идентификатором 100. Если такая область памяти не существует, то программа создает ее с помощью вызова shmget и устанавливает для нее разрешение на чтение-запись для всех пользователей. После открытия разделяемая память подсоединяется к виртуальному адресу процесса посредством вызова функции shmat. Затем программа записывает сообщение Hello в разделяемую область памяти и отсоединяет от нее процесс. После этого любой процесс может подсоединяться к разделяемой области и читать записанное в ней сообщение. tinclude tinclude tinclude tinclude tinclude tinclude tinclude <iostream.h> <stdio.h> <stdlib.h> <string.h> <sys/stat.h> <sys/ipc.h> <sys/shm.h> int main() { int perms = S IRWXU S IRWXG I S IRWXO; int fd = shmget (100, 1024, IPC CREAT perms); if (fd==-l) perror( shmget ), exit(l); char* addr = (char*)shmat(fd, 0, 0); if (addr==(char*)-1) perror( shmat ), exit(l); strcpy( addr, Hello ); 4;; if (shmdt (addr) ==-1) perror ( shmdt ) 4- return 0; it-- 10.7.6. Функция semctl Прототип функции semctl имеет следующий вид: #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmcd (int shmid, int cmd, struct shmid ds* buf ); С помощью этого API можно запрашивать управляющие параметры разделяемой области памяти, указанной аргументом shmid, изменять эти параметры и удалять данную область памяти. Значение shmid - это дескриптор разделяемой области памяти, полученный посредством вызова функции shmget. Аргумент buf - это адрес объекта типа struct shmid ds, который можно использовать для задания и выборки управляющих параметров разделяемой памяти, указанных аргументом cmd Ниже перечислены возможные значения аргумента cmd и вызываемые ими действия:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |