Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

14.5. Функция shmctl

Функция shmctl позволяет выполнять различные операции с сегментом разделяемой памяти:

#include <sys/shm.h>

int shmctl(int shmid, int and, struct shmid_ds *buff);

/* Возвращает 0 в случае успешного завершения, –1 в случае ошибки */

Команд (значений аргумента cmd) может быть три:

■ IPC_RMID — удаление сегмента разделяемой памяти с идентификатором shmid

из системы;

■ IPC_SET — установка значений полей структуры shmid_ds для сегмента разделяемой памяти равными значениям соответствующих полей структуры, на которую указывает аргумент buff: shm_perm.uid, shm_perm.gid, shm_perm.mode. Значение поля shm_ctime устанавливается равным текущему системному времени;

■ IPC_STAT — возвращает вызывающему процессу (через аргумент buff) текущее значение структуры shmid_ds для указанного сегмента разделяемой памяти.

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

В этом разделе приведено несколько примеров простых программ, иллюстрирующих работу с разделяемой памятью System V.

Программа shmget

Программа shmget, текст которой приведен в листинге 14.1, [1] создает сегмент разделяемой памяти, принимая из командной строки полное имя и длину сегмента.

Листинг 14.1. Создание сегмента разделяемой памяти System V указанного размера

1

Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.

//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 ] <pathname> <length>");

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 для удаления сегмента разделяемой памяти из системы.

Листинг 14.2. Удаление сегмента разделяемой памяти system V из системы

//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 <pathname>");

8 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);

9 Shmctl(id, IPC_RMID, NULL);

10 exit(0);

11 }

Программа shmwrite

В листинге 14.3 приведен текст программы shmwrite, которая заполняет сегмент разделяемой памяти последовательностью значений 0, 1, 2, …, 254, 255, 0, 1 и т. д.

Листинг 14.3. Заполнение сегмента разделяемой памяти последовательностью чисел

//svshm/shmwrite.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 int i, id;

6 struct shmid_ds buff;

7 unsigned char *ptr;

8 if (argc != 2)

9 err_quit("usage: shmwrite <pathname>");

10 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);

11 ptr = Shmat(id, NULL, 0);

12 Shmctl(id, IPC_STAT, &buff);

13 /* присваиваем: ptr[0] = 0, ptr[1] = 1 и т. д. */

14 for (i = 0; i < buff.shm_segsz; i++)

15 *ptr++ = i % 256;

16 exit(0);

17 }

10-12 Сегмент разделяемой памяти открывается вызовом shmget и подключается вызовом shmat. Его размер может быть получен вызовом shmctl с командой IPC_STAT.

13-15 В разделяемую память записывается последовательность значений.

Программа shmread

Программа shmread, текст которой приведен в листинге 14.4, проверяет последовательность значений, записанную в разделяемую память программой shmwrite.

Листинг 14.4. Проверка значений в сегменте разделяемой памяти

//svshm/shmread.c

1 #include "unpipc.h"

2 int

Поделиться с друзьями: