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

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

Функция shni unlink удаляет имя объекта разделяемой памяти. Как и другие подобные функции (удаление файла из файловой системы, удаление очереди сообщений и именованного семафора Posix), она не выполняет никаких действий до тех пор, пока объект не будет закрыт всеми открывшими его процессами. Однако после вызова shni unl i nk последующие вызовы open, mq open и seni open выполняться не будут.

13.3. функции ftruncate и fstat

Размер файла или объекта разделяемой памяти можно изменить вызовом

ftruncate:

finclude <unistd.h>

int ftruncateCint fd. off t length):

/* Возвращает 0 в случае успешного завершения. -1 - в случае ошибки */ Стандарт Posix делает некоторые различия в определении действия этой функции для обычных файлов и для объектов разделяемой памяти.

1. Для обычного файла: если размер файла превышает значение length, избыточные данные отбрасываются. Если размер файла оказывается меньше значения length, действие функции не определено. Поэтому для переносимости следует использовать следующий способ увеличения длины обычного файла: вызов Iseek со сдвигом length-1 и запись 1 байта в файл. К счастью, почти все реализации Unix поддерживают увеличение размера файла вызовом ftruncate.

2. Для объекта разделяемой памяти: ftruncate устанавливает размер объекта равным значению аргумента length.

Итак, мы вызываем ftruncate для установки размера только что созданного

объекта разделяемой памяти или изменения размера существующего объекта. При

открытии существующего объекта разделяемой памяти следует воспользоваться

fstat для получения информации о нем:

finclude <sys/types.h>

finclude <sys/stat.h>

int fstat(int fd. struct stat *buf):

/* Возвращает 0 в случае успешного завершения. -1 - в случае ошибки */ В структуре stat содержится больше десятка полей (они подробно описаны в главе 4 [21]), но только четыре из них содержат актуальную информацию, если fd представляет собой дескриптор области разделяемой памяти:

struct stat {

mode t st mode: /* mode: S I{RW}{USR.GRP.OTH} */ uid t st uid: /* UID владельца */ gid t st gid: /* GID владельца */ off t st size: /* размер в байтах */

Пример использования этих двух функций будет приведен в следующем разделе.



ПРИМЕЧАНИЕ

К сожалению, стандарт Posix никак не оговаривает начальное содержимое разделяе-Moii памяти. Описание функции slim open гласит, что объект разделяемой памяти будет иметь нулевой размер . Описание ftruncate гласит, что для обычных файлов (не объектов разделяемой памяти) при увеличении размера файла он будет дополнен нулями . Однако в этом описании ничего не говорится о содержимом разделяемой памяти. Обоснование Posix.l (Rationale) говорит, что разделяемая память при расширении дополняется нулями , но это не официальный стандарт. Когда автор попытался уточнить этот вопрос в конференции comp.std.unix, он узнал, что некоторые производители протестовали против введения требования на заполнение памяти нулями из-за возникающих накладных расходов. Если новая область памяти не инициализируется каким-то значением (то есть содержимое остается без изменения), это может угрожать безопасности системы.

13.4. Простые программы

Приведем несколько примеров программ, работающих с разделяемой памятью Posix.

Программа shmcreate

Программа slimcreate, текст которой приведен в листинге 13.1,* создает объект разделяемой памяти с указанным именем и длиной.

Листинг 13.1. Создание объекта разделяемой памяти Posix указанного размера

pxsfitti/slitticreate.c

1 finclude unpipcli

2 int

3 mainCint argc. cliar **argv)

5 int c. fd. flags:

6 char *ptr:

7 off t length:

8 flags = 0 RDWR 0 CREAT:

9 while ( (c = GetoptCargc. argv. e )) != -1) {

10 switch (c) {

11 case e:

12 flags 1= OJXCL:

13 breal<:

14 }

15 }

16 if (optind != argc - 2)

17 err quit( usage: shmcreate [ -e ] <name> <length> ):

18 length = atoi(argv[optind + 1]):

19 fd = Shm open(argv[optind]. flags. FILEJODE):

20 Ftruncate(fd. length):



21 ptr - MmapCNULL. length. PROT READ PROT WRITE. MAP SHARED. fd. 0):

22 ex1t(0):

23 }

19-22 Вызов shm open создает объект разделяемой памяти. Если указан параметр -е, будет возвращена ошибка в том случае, если такой объект уже существует. Вызов ftruncate устанавливает длину (размер объекта), а mmap отображает его содержимое в адресное пространство процесса. Затем программа завершает работу. Поскольку разделяемая память Posix обладает живучестью ядра, объект разделяемой памяти при этом не исчезает.

Программа shmunlink

в листинге 13.2 приведен текст тривиальной программы, удаляющей имя объекта разделяемой памяти из системы.

Листинг 13.2. Удаление имени объекта разделяемой памяти Posix

pxshtti/shttiunlink.c

1 finclude unpipc.h

2 int

3 mainCint argc. char **argv)

5 if (argc != 2)

6 err quit( usage: shmunlink <name> ):

7 Shm unlink(argv[l]):

8 exit(O):

Программа shmwrite

в листинге 13.3 приведен текст программы shmwrite, записывающей последовательность О, 1, 2,254, 244, 0,1 и т. д. в объект разделяемой памяти.

Листинг 13.3. Заполнение разделяемой памяти

pxshm/shmwrite.c

1 finclude unpipc.h

2 int

3 main(int argc. char **argv)

5 int i. fd:

6 struct stat stat:

7 unsigned char *ptr:

8 if (argc 1= 2)

9 err quit( usage: shmwrite <name> ):

10 /* open, определяем размер, отображаем в память */

11 fd = Shm open(argv[l]. 0 RDWR. FILE MCDE):

12 Fstat(fd. &stat):

13 ptr = Mmap(NULL. stat.st size. PROT READ PROT WRITE. про-Ьгит-тг-



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.
Копирование материалов разрешено исключительно при условии цититирования.