next up previous contents
Next: Операции над разделяемыми сегментами Up: Разделяемые сегменты памяти Previous: Создание разделяемых сегментов памяти.   Contents

Управление разделяемыми сегментами памяти.

В справочной статье shmctl синтаксис данного системного вызова описан так:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int shmctl (int shmid, int cmd, struct shmid_ds *buf);

При успешном завершении результат равен нулю; в случае неудачи возвращается -1.

В качестве аргумента shmid должен выступать идентификатор разделяемого сегмента памяти, предварительно полученный при помощи системного вызова shmget.

Управляющее действие определяется значением аргумента cmd. Допустимы следующие

значения:

IPC_STAT
- Поместить информацию о состоянии разделяемого сегмента, содержащуюся в структуре данных, ассоциированной с идентификатором shmid, в пользовательскую структуру, на которую указывает аргумент buf.
IPC_SET
- В структуре данных, ассоциированной с идентификатором shmid, переустановить значения действующих идентификаторов пользователя и группы, а также прав на операции. Нужные значения извлекаются из структуры данных, на которую указывает аргумент buf.
IPC_RMID
- Удалить из системы идентификатор shmid, ликвидировать разделяемый сегмент памяти и ассоциированную с ним структуру данных.
SHM_LOCK
- Удерживать в памяти разделяемый сегмент, заданный идентификатором shmid.
SHM_UNLOCK
- Освободить (перестать удерживать в памяти) разделяемый сегмент, заданный идентификатором shmid.
Чтобы выполнить управляющее действие IPC_SET или IPC_RMID, процесс должен иметь действующий идентификатор пользователя, равный либо идентификаторам создателя или владельца очереди, либо идентификатору суперпользователя.

Управляющие действия SHM_LOCK и SHM_UNLOCK может выполнить только суперпользователь. Для выполнения управляющего действия IPC_STAT процессу требуется право на чтение (рис. 22).

/* Программа иллюстрирует

возможности системного вызова shmctl()

(операции управления разделяемыми сегментами) */

 

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

 

main ()

{

  extern int errno;

  int rtrn, shmid, command, choice;

  struct shmid_ds shmid_ds, *buf;

  buf = &shmid_ds;

 

  /* Ввести идентификатор сегмента и действие */

  printf ("Введите идентификатор shmid: ");

  scanf ("%d", &shmid);

  printf ("Введите номер требуемого действия:\n");

  printf (" IPC_STAT = 1\n");

  printf (" IPC_SET = 2\n");

  printf (" IPC_RMID = 3\n");

  printf (" SHM_LOCK = 4\n");

  printf (" SHM_UNLOCK = 5\n");

  printf (" Выбор = ");

  scanf ("%d", &command);

 

  /* Проверить значения */

  printf ("\nидентификатор = %d, действие = %d\n",

          shmid, command);

  switch (command) {

          case 1: /* Скопировать информацию

                  о состоянии разделяемого сегмента

                  в пользовательскую структуру

                  и вывести ее */

                  rtrn = shmctl (shmid, IPC_STAT, buf);

                  printf ("\nИд-р пользователя = %d\n",

                          buf->shm_perm.uid);

                  printf ("Ид-р группы пользователя = %d\n",

                          buf->shm_perm.gid);

                  printf ("Ид-р создателя = %d\n",

                          buf->shm_perm.cuid);

                  printf ("Ид-р группы создателя = %d\n",

                          buf->shm_perm.cgid);

                  printf ("Права на операции = 0%o\n",

                          buf->shm_perm.mode);

                  printf ("Последовательность номеров ");

                          buf->shm_perm.cgid);

                  printf ("используемых слотов = 0%x\n",

                           buf->shm_perm.seq);

                  printf ("Ключ = 0%x\n", buf->shm_perm.key);

                  printf ("Размер сегмента = %d\n", buf->shm_segsz);

                  printf ("Выполнил последнюю операцию = %d\n",

                           buf->shm_lpid);

                  printf ("Создал сегмент = %d\n", buf->shm_cpid);

                  printf ("Число присоединивших сегмент = %d\n",

                           buf->shm_nattch);

                  printf ("Число удерживаюших в памяти = %d\n",

                           buf->shm_cnattch);

                  printf ("Последнее присоединение = %d\n",

                           buf->shm_atime);

                  printf ("Последнее отсоединение = %d\n",

                           buf->shm_dtime);

                  printf ("Последнее изменение = %d\n",

                           buf->shm_ctime);

                  break;

          case 2: /* Выбрать и изменить поле (поля)

                  ассоциированной структуры данных */

                  /* Получить исходные значения структуры данных */

                  rtrn = shmctl (shmid, IPC_STAT, buf);

                  printf ("Введите номер изменяемого поля:\n");

                  printf (" shm_perm.uid = 1\n");

                  printf (" shm_perm.gid = 2\n");

                  printf (" shm_perm.mode = 3\n");

                  printf (" Выбор = ");

                  scanf ("%d", &choice);

                  switch (choice) {

                         case 1:

                                printf ("\nВведите ид-р пользователя:"),

                                scanf ("%d", &buf->shm_perm.uid);

                                printf ("\nИд-р пользователя = %d\n",

                                        buf->shm_perm.uid);

                                break;

                         case 2:

                                printf ("\nВведите ид-р группы: "),

                                scanf ("%d", &buf->shm_perm.gid);

                                printf ("\nИд-р группы = %d\n",

                                        buf->shm_perm.uid);

                                break;

                         case 3:

                                printf ("\nВведите восьмеричный

                                       код прав: ");

                                scanf ("%o", &buf->shm_perm.mode);

                                printf ("\nПрава на операции

                                        = 0%o\n",

                                        buf->shm_perm.mode);

                                break;

                     }

                  /* Внести изменения */

                  rtrn = shmctl (shmid, IPC_SET, buf);

                  break;

          case 3: /* Удалить идентификатор и

                  ассоциированную структуру данных */

                  rtrn = shmctl (shmid, IPC_RMID, NULL);

                  break;

          case 4: /* Удерживать разделяемый сегмент

                  в памяти */

                  rtrn = shmctl (shmid, SHM_LOCK, NULL);

                  break;

          case 5: /* Перестать удерживать сегмент в памяти */

                  rtrn = shmctl (shmid, SHM_UNLOCK, NULL);

  }

  if (rtrn == -1) {

           /* Сообщить о неудачном завершении */

           printf ("\nshmctl завершился неудачей!\n");

           printf ("\nКод ошибки = %d\n", errno);

  }

  else {

           /* При успешном завершении сообщить ид-р shmid */

           printf ("\nshmctl завершился успешно, ");

           printf ("идентификатор shmid = %d\n", shmid);

  }

  exit (0);

}

Рис. 22. Управление разделяемой памятью.


next up previous contents
Next: Операции над разделяемыми сегментами Up: Разделяемые сегменты памяти Previous: Создание разделяемых сегментов памяти.   Contents
2003-12-09