Главная страница Взаимодействие нетривиальных процессов который затем передается функции шар. Результат аналогичен отображению файла в память, но разделяемая память Posix не обязательно реализуется через файл. Поскольку доступ к объектам разделяемой памяти может быть получен через дескриптор, для установки размера объекта используется функция ftruncate, а информация о существующем объекте (биты разрешений, идентификаторы пользователя и группы, размер) возвращается функцией fstat. В главах, рассказывающих об очередях сообщений и семафорах Posix, мы приводили примеры их реализации через отображение в память (разделы 5.8 и 10.15). Для разделяемой памяти Posix мы этого делать не будем, поскольку реализация тривиальна. Если мы готовы использовать отображение в файл (что и сделано в Solaris и Digital Unix), shni open реализуется через open, а shni unl i nk - через unl i nk. Упражнения 1. Измените программы из листингов 12.6 и 12.7 таким образом, чтобы они работали с разделяемой памятью Posix, а не с отображаемым в память файлом. Убедитесь, что результаты будут такими же, как и для отображаемого в память файла. 2. В циклах for в листингах 13.3 и 13.4 используется команда *ptr++ для перебора элементов массива. Не лучше ли было бы использовать ptr[i ]? ГЛАВАМ Разделяемая память System V 14.1. Введение Основные принципы разделяемой памяти System V совпадают с концепцией разделяемой памяти Posix. Вместо вызовов shni open и mmap в этой системе используются вызовы shmget и shmat. Для каждого сегмента разделяемой памяти ядро хранит нижеследующую структуру, определенную в заголовочном файле <sys/shm.h>: struct shttnd ds { struct ipc pertti shtti pertti; /* структура разрешений */ size t shtti segsz; /* размер сегмента */ pid t shttijpid: /* идентификатор процесса, выполнившего последнюю операцию */ pld t shtti cpid: /* идентификатор процесса-создателя */ shttiatt t shtti nattch; /* текущее количество подключений */ shmat t shm cnattch; /* количество подключений in-core */ time t shm atime time t shm dtime time t shm ctime /* время последнего подключения */ /* время последнего отключения */ /* время последнего изменения данной структуры */ Структура i pc perm была описана в разделе 3.3; она содержит разрешения доступа к сегменту разделяемой памяти. 14.2. Функция shmget С помощью функции shmget можно создать новый сегмент разделяемой памяти или подключиться к существующему: #include <sys/shm.h> int shmget(key t key. size t size, int oflag): I* Возвращает идентификатор разделяемой памяти в случае успешного завершения. -1 -в случае ошибки */ Возвращаемое целочисленное значение называется идентификатором разделяемой памяти. Он используется с тремя другими функциями shmXXX. Аргумент key может содержать значение, возвращаемое функцией ftok, или константу IPC PRIVATE, как обсуждалось в разделе 3.2. Аргумент size указывает размер сегмента в байтах. При создании нового сегмента разделяемой памяти нужно указать ненулевой размер. Если производится обращение к существующему сегменту, аргумент size должен быть нулевым. Флаг oflag представляет собой комбинацию флагов доступа на чтение и запись из табл. 3.3. К ним могут быть добавлены с помощью логического сложения флаги IPC CREAT или IPC CREAT IPC EXCL, как уже говорилось в связи с рис. 3.2. Новый сегмент инициализируется нулями. Обратите внимание, что функция shmget создает или открывает сегмент разделяемой памяти, но не дает вызвавшему процессу доступа к нему. Для подключения сегмента памяти предназначена функция shmat, описанная в следующем разделе. 14.3. Функция shmat После создания или открытия сегмента разделяемой памяти вызовом shmget его нужно подключить к адресному пространству процесса вызовом shmat: finclude <sys/shtti.h> void *shttiat(int shmid. const void *shmaddr. int flag): I* Возвращает начальный адрес полученной области в случае успешного завершения. -1 -в случае ошибки */ Аргумент shmid - это идентификатор разделяемой памяти, возвращенный shmget. Функция shmat возвращает адрес начала области разделяемой памяти в адресном пространстве вызвавшего процесса. Правила, по которым формируется этот адрес, таковы: ii если аргумент shmaddr представляет собой нулевой указатель, система сама выбирает начальный адрес для вызвавшего процесса. Это рекомендуемый (и обеспечивающий наилучшую совместимость) метод; ж если shmaddr отличен от нуля, возвращаемый адрес зависит от того, был ли указан флаг SHM RND (в аргументе flag): □ если флаг SHM RND не указан, разделяемая память подключается непосредственно с адреса, указанного аргументом shmaddr, □ если флаг SHM RND указан, сегмент разделяемой памяти подключается с адреса, указанного аргументом shmaddr, округленного вниз до кратного константе SHMLBA. Аббревиатура LBA означает lower boundary address - нижний граничный адрес. По умолчанию сегмент подключается для чтения и записи, если процесс обладает соответствующими разрешениями. В аргументе flag можно указать константу SHM RDONLY, которая позволит установить доступ только на чтение. 14.4. Функция shmdt После завершения работы с сегментом разделяемой памяти его следует отключить вызовом shmdt: finclude <sys/shtti.h> int shmdtCconst void *shmaddr): /* Возвращает 0 в случае успешного завершения. -1 - в случае ошибки */ При завершении работы процесса все сегменты, которые не были отключены им явно, отключаются автоматически.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |