The OpenNET Project / Index page

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

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

Очереди сообщений

  /* Программа иллюстрирует
     возможности системного вызова msgget()
     (получение идентификатора очереди сообщений) */

  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/ipc.h>
  #include <sys/sem.h>
  #include <errno.h>

  main ()
  {
    key_t key;        /* Тип описан как целое */
    int opperm, flags;    /* Права на операции и флаги */
    int msgflg, msqid;

    /* Ввести требуемый ключ */
    printf ("\nВведите шестнадцатеричный ключ: ");
    scanf ("%x", &key);

    /* Ввести права на операции */
    printf ("\nВведите права на операции ");
    printf ("в восьмеричной записи: ");
    scanf ("%o", &opperm);

    /* Установить требуемые флаги */
    printf ("\nВведите код, соответствущий ");
    printf ("нужной комбинации флагов:\n");
    printf ("  Нет флагов           = 0\n");
    printf ("  IPC_CREAT            = 1\n");
    printf ("  IPC_EXCL             = 2\n");
    printf ("  IPC_CREAT и IPC_EXCL = 3\n");
    printf ("  Выбор                = ");

    /* Получить флаги, которые нужно установить */
    scanf ("%d", &flags);

    /* Проверить значения */
    printf ("\nключ = 0x%x, права = 0%o, флаги = %d\n",
            key, opperm, flags);

    /* Объединить флаги с правами на операции */
  switch (flags) {
    case 0:     /* Флаги не устанавливать */
      msgflg = (opperm | 0);
      break;
    case 1:     /* Установить флаг IPC_CREAT */
      msgflg = (opperm | IPC_CREAT);
      break;
    case 2:     /* Установить флаг IPC_EXCL */
      msgflg = (opperm | IPC_EXCL);
      break;
    case 3:     /* Установить оба флага */
      msgflg = (opperm | IPC_CREAT | IPC_EXCL);
  }

  /* Выполнить системный вызов msgget */
  msqid = msgget (key, msgflg);

  if (msqid == -1) {
    /* Сообщить о неудачном завершении */
    printf ("\nmsgget завершился неудачей!\n"
    printf ("Код ошибки = %d\n", errno);
  }
  else
    /* При успешном завершении сообщить msqid */
    printf ("\nИдентификатор msqid = %d\n", msqid);

  exit (0);
  }



 /* Программа иллюстрирует
    возможности системного вызова msgctl()
    (управление очередями сообщений) */

 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>

 main ()
 {
   extern int errno;
   int msqid, command, choice, rtrn;
   struct msqid_ds msqid_ds, *buf;
   buf = &msqid_ds;

   /* Ввести идентификатор и действие */
   printf ("Введите идентификатор msqid: ");
   scanf ("%d", &msqid);

   printf ("Введите номер требуемого действия:\n");
   printf ("  IPC_STAT = 1\n");
   printf ("  IPC_SET  = 2\n");
   printf ("  IPC_RMID = 3\n");
   printf ("  Выбор    = ");
   scanf ("%d", &command);

   /* Проверить значения */
   printf ("идентификатор = %d, действие = %d\n",
           msqid, command);

   switch (command) {
     case 1: /* Скопировать информацию
                о состоянии очереди сообщений
                в пользовательскую структуру
                и вывести ее */
       rtrn = msgctl (msqid, IPC_STAT, buf);
       printf ("\n Идентификатор пользователя = %d\n",
               buf->msg_perm.uid);
       printf ("\n Идентификатор группы = %d\n",
               buf->msg_perm.gid);
       printf ("\n Права на операции = 0%o\n",
               buf->msg_perm.mode);
       printf ("\n Размер очереди в байтах = %d\n",
               buf->msg_qbytes);
       break;

     case 2: /* Выбрать и изменить поле (поля)
                 ассоциированной структуры данных */
       /* Сначала получить исходное значение
          структуры данных */
       rtrn = msgctl (msqid, IPC_STAT, buf);
       printf ("\nВведите номер поля, ");
       printf ("которое нужно изменить:\n");
       printf ("  msg_perm.uid  = 1\n");
       printf ("  msg_perm.gid  = 2\n");
       printf ("  msg_perm.mode = 3\n");
       printf ("  msg_qbytes    = 4\n");
       printf ("  Выбор         = ");
       scanf ("%d", &choice);

       switch (choice) {
         case 1:
           printf ("\nВведите ид-р пользователя: ");
           scanf ("%d", &buf->msg_perm.uid);
           printf ("\nИд-р пользователя = %d\n",
                   buf->msg_perm.uid);
           break;
         case 2:
           printf ("\nВведите ид-р группы: ");
           scanf ("%d", &buf->msg_perm.gid);
           printf ("\nИд-р группы = %d\n",
                   buf->msg_perm.uid);
           break;

         case 3:
           printf ("\nВведите восьмеричный код прав: ");
           scanf ("%o", &buf->msg_perm.mode);
           printf ("\nПрава на операции = 0%o\n",
                   buf->msg_perm.mode);
           break;

         case 4:
           printf ("\nВведите размер очереди = ");
           scanf ("%d", &buf->msg_qbytes);
           printf ("\nЧисло байт в очереди = %d\n",
                   buf->msg_qbytes);
           break;
       }

       /* Внести изменения */
       rtrn = msgctl (msqid, IPC_SET, buf);
       break;

    case 3: /* Удалить идентификатор и
               ассоциированные с ним очередь
               сообщений и структуру данных */
      rtrn = msgctl (msqid, IPC_RMID, NULL);
   }

   if (rtrn == -1) {
     /* Сообщить о неудачном завершении */
     printf ("\nmsgctl завершился неудачей!\n");
     printf ("\nКод ошибки = %d\n", errno);
   }

   else {
     /* При успешном завершении сообщить msqid */
     printf ("\nmsgctl завершился успешно,\n");
     printf ("идентификатор = %d\n", msqid);
   }

   exit (0);
 }


 /* Программа иллюстрирует
    возможности системных вызовов msgsnd() и msgrcv()
    (операции над очередями сообщений) */

 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>

 #define MAXTEXTSIZE 8192

 struct msgbufl {
   long mtype;
   char mtext [MAXTEXTSIZE];
 } sndbuf, rcvbuf, *msgp;

 main ()
 {
   extern int errno;
   int flag, flags, choice, rtrn, i, c;
   int rtrn, msqid, msgsz, msgflg;
   long msgtyp;
   struct msqid_ds msqid_ds, *buf;
   buf = &msqid_ds;

   /* Выбрать требуемую операцию */
   printf ("\nВведите код, соответствующий ");
   printf ("посылке или приему сообщения:\n");
   printf ("  Послать = 1\n");
   printf ("  Принять = 2\n");
   printf ("  Выбор   = ");
   scanf ("%d", &choice);

   if (choice == 1) {
     /* Послать сообщение */
     msgp = &sndbuf; /* Указатель на структуру */

     printf ("\nВведите идентификатор ");
     printf ("очереди сообщений,\n");
     printf ("в которую посылается сообщение: ");
     scanf ("%d", &msqid);

     /* Установить тип сообщения */
     printf ("\nВведите положительное число - ");
     printf ("тип сообщения: ");
     scanf ("%d", &msgp->mtype);

     /* Ввести посылаемое сообщение */
     printf ("\nВведите сообщение: \n");

     /* Управляющая последовательность CTRL+D
        завершает ввод сообщения */

     /* Прочитать символы сообщения
        и поместить их в массив mtext */
     for (i = 0; ((c = getchar ()) != EOF); i++)
       sndbuf.mtext [i] = c;

     /* Определить размер сообщения */
     msgsz = i + 1;

     /* Выдать текст посылаемого сообщения */
     for (i = 0; i < msgsz; i++)
       putchar (sndbuf.mtext [i]);

     /* Установить флаг IPC_NOWAIT, если это нужно */
     printf ("\nВведите 1, если хотите установить ");
     printf ("флаг IPC_NOWAIT: ");
     scanf ("%d", &flag);
     if (flag == 1)
       msgflg = IPC_NOWAIT;
     else
       msgflg = 0;

     /* Проверить флаг */
     printf ("\nФлаг = 0%o\n", msgflg);

     /* Послать сообщение */
     rtrn = msgsnd (msqid, msgp, msgsz, msgflg);
     if (rtrn == -1) {
       printf ("\nmsgsnd завершился неудачей!\n");
       printf ("Код ошибки = %d\n", errno);
     }
     else {
       /* Вывести результат; при успешном
          завершении он должен равняться нулю */
       printf ("\nРезультат = %d\n", rtrn);

       /* Вывести размер сообщения */
       printf ("\nРазмер сообщения = %d\n", msgsz);

       /* Опрос измененной структуры данных */
       msgctl (msqid, IPC_STAT, buf);

       /* Вывести изменившиеся поля */
       printf ("Число сообщений в очереди = %d\n",
               buf->msg_qnum);
       printf ("Ид-р последнего отправителя = %d\n",
               buf->msg_lspid);
       printf ("Время последнего отправления = %d\n",
               buf->msg_stime);
     }
   }

   if (choice == 2) {
     /* Принять сообщение */
     msgp = &rcvbuf;

     /* Определить нужную очередь сообщений */
     printf ("\nВведите ид-р очереди сообщений: ");
     scanf ("%d", &msqid);

     /* Определить тип сообщения */
     printf ("\nВведите тип сообщения: ");
     scanf ("%d", &msgtyp);

     /* Сформировать управляющие флаги
        для требуемых действий */
     printf ("\nВведите код, соответствущий ");
     printf ("нужной комбинации флагов:\n");
     printf ("  Нет флагов               = 0\n");
     printf ("  MSG_NOERROR              = 1\n");
     printf ("  IPC_NOWAIT               = 2\n");
     printf ("  MSG_NOERROR и IPC_NOWAIT = 3\n");
     printf ("  Выбор                    = ");
     scanf ("%d", &flags);

     switch (flags) {
       /* Установить msgflg как побитное ИЛИ
          соответствующих констант */
       case 0:
         msgflg = 0;
         break;
       case 1:
         msgflg = MSG_NOERROR;
         break;
       case 2:
         msgflg = IPC_NOWAIT;
         break;
       case 3:
         msgflg = MSG_NOERROR | IPC_NOWAIT;
         break;
     }

     /* Определить, какое число байт принять */
     printf ("\nВведите число байт, которое ");
     printf ("нужно принять (msgsz): ");
     scanf ("%d", &msgsz);

     /* Проверить значение аргументов */
     printf ("\nИдентификатор msqid = %d\n", msqid);
     printf ("Тип сообщения = %d\n", msgtyp);
     printf ("Число байт = %d\n", msgsz);
     printf ("Флаги = %o\n", msgflg);

     /* Вызвать msgrcv для приема сообщения */
     rtrn = msgrcv (msqid, msgp, msgsz, msgtyp, msgflg);

     if (rtrn == -1) {
       printf ("\nmsgrcv завершился неудачей!\n");
       printf ("Код oшибки = %d\n", errno);
     }
     else {
       printf ("\nmsgrcv завершился успешно,\n");
       printf ("идентификатор очереди = %d\n", msqid);

         /* Напечатать число принятых байт,
            оно равно возвращаемому значению */
         printf ("Принято байт: %d\n", rtrn);

         /* Распечатать принятое сообщение */
         for (i = 0; i < rtrn; i++)
           putchar (rcvbuf.mtext [i]);
     }

     /* Опрос ассоциированной структуры данных */
     msgctl (msqid, IPC_STAT, buf);

     printf ("\nЧисло сообщений в очереди = %d\n",
             buf->msg_qnum);
     printf ("Ид-р последнего получателя = %d\n",
             buf->msg_lrpid);
     printf ("Время последнего получения = %d\n",
             buf->msg_rtime);
   }

   exit (0);
 }



Alex Otwagin 2002-12-16



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

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