Главная страница Взаимодействие нетривиальных процессов Листинг 14.4 (продолжение) 14 for (i = 0; 1 < buff.shtti segsz; i++) 15 1f ( (с = *ptr++) != (i X 256)) 16 err retCptr[d] = Xd . i. c); 17 exlt(0); 18 } 10-12 Открываем и подключаем сегаент разделяемой памяти. Его размер может быть получен вызовом shmctl с командой IPCSTAT. 13-16 Проверяется последовательность, записанная программой shmwrite. Примеры Создадим сегмент разделяемой памяти длиной 1234 байта в системе Solaris 2.6. Для идентификации сегмента используем полное имя нашего исполняемого файла shmget. Это имя будет передано функции ftok. Имя исполняемого файла сервера часто используется в качестве уникального идентификатора для данного приложения: Solaris X shmget shmget 1234 Solaris X ipcs -Ьпю IPC status from <running system> as of Thu Jan 8 13:17:06 1998 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: m 1 0x0000fl2a --rw-r--r-- rstevens otherl 0 1234 Программу i pes мы запускаем для того, чтобы убедиться, что сегмент разделяемой памяти действительно был создан и не был удален по завершении программы shmcreate. Количество подключений (хранящееся в поле shm nattch структуры shmid ds) равно нулю, как мы и предполагали. Теперь запустим программу shmwrite, чтобы заполнить содержимое разделяемой памяти последовательностью значений. Затем проверим содержимое сегмента разделяемой памяти программой shmread и удалим этот сегмент: Solaris X shmwrite shmget Solaris X shmread shmget Solaris X shmrmid shmget Solaris X ipcs -bmo IPC status from <running system> as of Thu Jan 8 13:17:06 1998 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory: Мы используем программу ipcs, чтобы убедиться, что сегмент разделяемой памяти действительно был удален. ПРИМЕЧАНИЕ При использовании имени исполняемого файла сервера в качестве аргумента ftok для идентификации какого-либо вида IPC System V обычно передается полное имя этого файла (например, /usr/bin/myserverd), а не часть имени, как сделано у нас (slimget). У нас не возникло проблем в этом примере, потому что все программы запускались из того же каталога, в котором был расположен исполняемый файл сервера. Вы помните, что функция ftok использует номер i-node файла для формирования ключа IPC и ей безразлично, определяется файл своим полным именем или его частью (относительным именем).
Пример Программа в листинге 14.5 определяет значения четырех ограничений, приведенных в табл. 14.1. Листинг 14.5. Определение системных ограничений на разделяемую память svshtti/littiits.c 1 finclude unpipc.h 2 fdefine MAXJIDS 4096 3 int 4 mainCint argc, char **argv) 6 int i, j, shmid[MAX NIDS]; 7 void *addr[MAX NIDS]; 8 unsigned long size; 9 /* проверка максимального количества открываемых идентификаторов */ 10 for (1 - 0; i <= MAX NIDS; i++) { 11 shmid[i] - shmgit(IPC PRIVATE, 1024, SVSHM MODE IPC CREAT): 12 if (shmid[i] - -1) { 13 printf( d identifiers open at once\n , i): 14 break; 15 } 16 } 17 for (j = 0: j < i: 18 Shmctl(shmidlj], IPC RMID, NULL); 19 /* определяем максимальное количество подключаемых сегментов */ 20 for (i =0; i <= MAXJIDS; i..) { продолжение 14.7. Ограничения, накладываемые на разделяемую память На разделяемую память System V накладываются определенные ограничения точно так же, как и на семафоры и очереди сообщений System V (раздел 3.8). В табл. 14.1 приведены значения этих ограничений для разных реализаций. В первом столбце приведены традиционные для System V имена переменных ядра, в которых хранятся эти ограничения. Таблица 14.1. Типичные значения ограничений, накладываемых на разделяемую память System V Листинг 14.5 (продолжение) 21 shttiid[i] = Shmget(IPC PRIVATE, 1024. SVSHM MODE IPC CREAT): 22 addr[1] - shttiat(shttiid[i]. NULL, 0)-, 23 if (addr[i] == (void *) -1) { 24 printf( *d shared memory segments attached at once\n , i); 25 Shmctl(shmid[i], IPC RMID, NULL): /* удаляем неудачно подключенный сегмент */ 26 break; 27 } 28 } 29 for (j = 0: j < i: j++) { 30 Shmdt(addr[j]): 31 Shmctl(shmid[j], IPC RMID. NULL): 32 } 33 /* проверка минимального размера сегмента */ 34 for (size = 1; : size++) { 35 shmid[0] = shmget(IPC PRIVATE, size. SVSHM MODE IPC CREAT): 36 if (shmid[0] != -1) { /* выход при успешном создании */ 37 printf( minimum size of shared memory segment = *lu\n , size): 38 Shmctl(shmid[0], IPC RMID, NULL): 39 break: 40 } 41 } 42 /* определение максимального размера сегмента */ 43 for (size = 65536: : size += 4096) { 44 shmid[0] = shmget(IPC PRIVATE, size. SVSHM MODE IPC CREAT): 45 if (shmid[0] == -1) { /* выход при ошибке */ 46 printf( maximum size of shared memory segment = *lu\n . size-4096); 47 break: 48 } 49 Shmctl(shmid[0], IPC RMID, NULL): 50 } 51 exit(O): 52 } Запустив эту программу в Digital Unix 4.0В, увидим: alpha % limits 127 identifiers open at once 32 shared memory segments attached at once minimum size of shared memory segment = 1 maximum size of shared memory segment = 4194304 Причина, no которой в табл. 14.1 приведено значение 128 для числа идентификаторов, а наша программа выводит значение 127, заключается в том, что один сегмент разделяемой памяти всегда используется системным демоном. 14.8. Резюме Разделяемая память System V похожа на разделяемую память Posix. Наиболее схожи функции: ш shmget для получения идентификатора;
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |