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 процессу требуется право на чтение:

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

возможности системного вызова 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);

}


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