Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 [ 115 ] 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

который затем передается функции шар. Результат аналогичен отображению файла в память, но разделяемая память 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 - в случае ошибки */ При завершении работы процесса все сегменты, которые не были отключены им явно, отключаются автоматически.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 [ 115 ] 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.