■ если
□ если флаг SHM_RND не указан, разделяемая память подключается непосредственно с адреса, указанного аргументом
□ если флаг SHM_RND указан, сегмент разделяемой памяти подключается с адреса, указанного аргументом
По умолчанию сегмент подключается для чтения и записи, если процесс обладает соответствующими разрешениями. В аргументе
14.4. Функция shmdt
После завершения работы с сегментом разделяемой памяти его следует отключить вызовом shmdt:
#include
int shmdt(const void
/* Возвращает 0 в случае успешного завершения, –1 – в случае ошибки */
При завершении работы процесса все сегменты, которые не были отключены им явно, отключаются автоматически.
Обратите внимание, что эта функция не удаляет сегмент разделяемой памяти. Удаление осуществляется функцией shmctl с командой IPC_RMIO.
14.5. Функция shmctl
Функция shmctl позволяет выполнять различные операции с сегментом разделяемой памяти:
#include
int shmctl(int
/* Возвращает 0 в случае успешного завершения, –1 в случае ошибки */
Команд (значений аргумента
■ IPC_RMID — удаление сегмента разделяемой памяти с идентификатором
■ IPC_SET — установка значений полей структуры shmid_ds для сегмента разделяемой памяти равными значениям соответствующих полей структуры, на которую указывает аргумент
■ IPC_STAT — возвращает вызывающему процессу (через аргумент
14.6. Простые программы
В этом разделе приведено несколько примеров простых программ, иллюстрирующих работу с разделяемой памятью System V.
Программа shmget
Программа shmget, текст которой приведен в листинге 14.1,[1] создает сегмент разделяемой памяти, принимая из командной строки полное имя и длину сегмента.
//svshm/shmget.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int c, id, oflag;
6 char *ptr;
7 size_t length;
8 oflag = SVSHM_MODE | IPC_CREAT;
9 while ((c = Getopt(argc, argv, "e")) != –1) {
10 switch (c) {
11 case 'e':
12 oflag |= IPC_EXCL;
13 break;
14 }
15 }
16 if (optind != argc – 2)
17 err_quit("usage: shmget [ –e ]
18 length = atoi(argv[optind + 1]);
19 id = Shmget(Ftok(argv[optind], 0), length, oflag);
20 ptr = Shmat(id, NULL, 0);
21 exit(0);
22 }
19 Вызов shmget создает сегмент разделяемой памяти указанного размера. Полное имя, передаваемое в качестве аргумента командной строки, преобразуется в ключ IPC System V вызовом ftok. Если указан параметр –е, наличие существующего сегмента с тем же именем приведет к возвращению ошибки. Если мы знаем, что сегмент уже существует, в командной строке должна быть указана нулевая длина.
20 Вызов shmat подключает сегмент к адресному пространству процесса. После этого программа завершает работу. Разделяемая память System V обладает поменьшей мере живучестью ядра, поэтому сегмент разделяемой памяти при этом не удаляется.
Программа shmrmid
В листинге 14.2 приведен текст тривиальной программы shmrmid, которая вызывает shmctl с командой IPC_RMID для удаления сегмента разделяемой памяти из системы.
//svshm/shmrmid.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int id;
6 if (argc != 2)
7 err_quit("usage: shmrmid
8 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);
9 Shmctl(id, IPC_RMID, NULL);
10 exit(0);