ПРИМЕЧАНИЕ
К сожалению, стандарт Posix никак не оговаривает начальное содержимое разделяемой памяти. Описание функции shm_open гласит, что «объект разделяемой памяти будет иметь нулевой размер». Описание ftruncate гласит, что для обычных файлов (не объектов разделяемой памяти) «при увеличении размера файла он будет дополнен нулями». Однако в этом описании ничего не говорится о содержимом разделяемой памяти. Обоснование Posix.1 (Rationale) говорит, что «разделяемая память при расширении дополняется нулями», но это не официальный стандарт. Когда автор попытался уточнить этот вопрос в конференции comp.std.unix, он узнал, что некоторые производители протестовали против введения требования на заполнение памяти нулями из-за возникающих накладных расходов. Если новая область памяти не инициализируется каким-то значением (то есть содержимое остается без изменения), это может угрожать безопасности системы.
13.4. Простые программы
Приведем несколько примеров программ, работающих с разделяемой памятью Posix.
Программа shmcreate
Программа shmcreate, текст которой приведен в листинге 13.1,[1] создает объект разделяемой памяти с указанным именем и длиной.
//pxshm/shmcreate.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int c, fd, flags;
6 char *ptr;
7 off_t length;
8 flags = O_RDWR | O_CREAT;
9 while ((c = Getopt(argc, argv, "e")) != –1) {
10 switch (c) {
11 case 'e':
12 flags |= O_EXCL;
13 break;
14 }
15 }
16 if (optind != argc – 2)
17 err_quit("usage: shmcreate [ –e ]
18 length = atoi(argv[optind + 1]);
19 fd = Shm_open(argv[optind], flags, FILE_MODE);
20 Ftruncate(fd, length);
21 ptr = Mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
22 exit(0);
23 }
19-22 Вызов shm_open создает объект разделяемой памяти. Если указан параметр –е, будет возвращена ошибка в том случае, если такой объект уже существует. Вызов ftruncate устанавливает длину (размер объекта), a mmap отображает его содержимое в адресное пространство процесса. Затем программа завершает работу. Поскольку разделяемая память Posix обладает живучестью ядра, объект разделяемой памяти при этом не исчезает.
Программа shmunlink
В листинге 13.2 приведен текст тривиальной программы, удаляющей имя объекта разделяемой памяти из системы.
//pxshm/shmunlink.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 if (argc != 2)
6 err_quit("usage: shmunlink
7 Shm_unlink(argv[1]);
8 exit(0);
9 }
Программа shmwrite
В листинге 13.3 приведен текст программы shmwrite, записывающей последовательность 0, 1, 2 254, 244, 0, 1 и т. д. в объект разделяемой памяти.
//pxshm/shmwrite.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int i, fd;
6 struct stat stat;
7 unsigned char *ptr;
8 if (argc != 2)
9 err_quit("usage: shmwrite
10 /* open, определяем размер, отображаем в память */