The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Документация для Linux" / Оглавление документа
next up previous contents index
Next: Работа с сокетами Up: Примеры Previous: Семафоры   Contents   Index

Разделяемые сегменты памяти

        /* Программа иллюстрирует
           возможности системного вызова 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);
      }



        /* Программа иллюстрирует
           возможности системных вызовов shmat() и shmdt()
           (операции над разделяемыми сегментами памяти) */
        #include <stdio.h>
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/shm.h>

        main ()
        {
          extern int errno;
          int shmid, shmaddr, shmflg;
          int flags, attach, detach, rtrn, i;

          /* Цикл присоединений для данного процесса */
          printf ("\nВведите число присоединений ");
          printf ("для процесса (1-4): ");
          scanf ("%d", &attach);
          printf ("\nЧисло присоединений = %d\n", attach);

          for (i = 0; i < attach; i++) {
            /* Ввести идентификатор разделяемого сегмента */
            printf ("\nВведите ид-р разделяемого сегмента,\n");
            printf ("над которым нужно выполнить операции: ");
            scanf ("%d", &shmid);
            printf ("\nИд-р сегмента = %d\n", shmid);

            /* Ввести адрес присоединения */
            printf ("\nВведите адрес присоединения ");
            printf ("в шестнадцатеричной записи: ");
            scanf ("%x", &shmaddr);
            printf ("\nАдрес присоединения = 0x%x\n", shmaddr);

       /* Выбрать требуемые флаги */
       printf ("\nВведите номер нужной комбинации флагов:\n");
       printf ("  SHM_RND              = 1\n");
       printf ("  SHM_RDONLY           = 2\n");
       printf ("  SHM_RND и SHM_RDONLY = 3\n");
       printf ("  Выбор                = ");
       scanf ("%d", &flags);

       switch (flags) {
         case 1:
           shmflg = SHM_RND;
           break;
         case 2:
           shmflg = SHM_RDONLY;
           break;
         case 3:
           shmflg = SHM_RND | SHM_RDONLY;
           break;
       }
       printf ("\nФлаги = 0%o", shmflg);

       /* Выполнить системный вызов shmat */
       rtrn = shmat (shmid, shmaddr, shmflg);
       if (rtrn == -1) {
         printf ("\nshmat завершился неудачей!\n");
         printf ("\Код ошибки = %d\n", errno);
       }
       else {
         printf ("\nshmat завершился успешно.\n");
         printf ("Идентификатор shmid = %d\n", shmid);
         printf ("Адрес = 0x%x\n", rtrn);
       }
     }

     /* Цикл отсоединений для данного процесса */
     printf ("\nВведите число отсоединений ");
     printf ("для процесса (1-4): ");
     scanf ("%d", &detach);
     printf ("\nЧисло отсоединений = %d\n", detach);

     for (i = 0; i < detach; i++) {
       /* Ввести адрес отсоединения */
       printf ("\nВведите адрес отсоединяемого сегмента ");
       printf ("в шестнадцатеричной записи: ");
       scanf ("%x", &shmaddr);
       printf ("\nАдрес отсоединения = 0x%x\n", shmaddr);

       /* Выполнить системный вызов shmdt */
       rtrn = shmdt (shmaddr);
       if (rtrn == -1) {
         printf ("\nshmdt завершился неудачей!\n");
         printf ("\Код ошибки = %d\n", errno);
       }
       else {
         printf ("\nshmdt завершился успешно,\n");
         printf ("идентификатор shmid = %d\n", shmid);
       }
     }

     exit (0);
   }



Alex Otwagin 2002-12-16



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру