![]() |
![]() |
Главная страница Взаимодействие нетривиальных процессов Функция 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. про-Ьгит-тг-
|
© 2000 - 2025 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |