Распечатка 7.8 Операции с очередью сообщений POSIX

Предыдущая  Содержание  Следующая V*D*V

Распечатка 7.8.

 

/* mqueue-1.c */

 

/* Эта программа посылает сообщение в очередь */

#include <stdio.h>

#include <string.h>

#include <mqueue.h>

 

#define QUEUE_NAME "/my_queue"

#define PRIORITY   1

#define SIZE       256

 

int main(){

 

  mqd_t ds;

  char text[] = "Hello Posix World";

  struct mq_attr queue_attr;

 

  /*

   * Атрибуты нашей очереди. Они могут быть установлены только

   * при создании.

   */

  queue_attr.mq_maxmsg = 32; /* максимальное число сообщений

                               в очереди в один момент времени */

  queue_attr.mq_msgsize = SIZE; /* максимальный размер очереди */

 

  /*

   * Создаём новую очередь с именем "/my_queue" и открываем её

   * для отправки и приёма. Разрешения для файла очереди

   * устанавливаем как rw для владельца и не разрешаем ничего

   * для группы/других. Ограничения очереди заданы указанными

   * выше величинами.

   */

  if ((ds = mq_open(QUEUE_NAME, O_CREAT | O_RDWR , 0600,

                    &queue_attr)) == (mqd_t)-1){

    perror("Creating queue error");

    return -1;

  }

 

  /*

   * Посылаем сообщение в очередь с приоритетом 1. Чем больше,

   * число, тем выше приоритет. Сообщение с высоким приоритетом

   * вставляется перед сообщением с низким приоритетом. Для

   * сообщений с одинаковым приоритетом работает принцип

   * первый вошёл, первый вышел.

   */

  if (mq_send(ds, text, strlen(text), PRIORITY) == -1){

    perror("Sending message error");

    return -1;

  }

  /* Закрываем очередь... */

  if (mq_close(ds) == -1)

    perror("Closing queue error");

  return 0;

}

 

/* mqueue-2.c */

 

/* Эта программа принимает сообщение из очереди */

#include <stdio.h>

#include <mqueue.h>

#define QUEUE_NAME "/my_queue"

#define PRIORITY   1

#define SIZE       256

 

int main(){

 

  mqd_t ds;

  char new_text[SIZE];

  struct mq_attr attr, old_attr;

  int prio;

 

  /*

   * Открываем "/my_queue" для отправки и приёма. При приёме

   * сообщения не блокируемся (O_NONBLOCK). Разрешения для файла

   * очереди устанавливаем как rw для владельца и не разрешаем

   * ничего для группы/других.

   */

  if ((ds = mq_open(QUEUE_NAME, O_RDWR | O_NONBLOCK, 0600,

                    NULL)) == (mqd_t)-1){

    perror("Creating queue error");

    return -1;

  }

 

  /*

   * Меняем приём на блокирующий. (Это сделано, чтобы

   * продемонстрировать использование функций mq_setattr и

   * mq_getattr. Чтобы перевести очередь в блокирующим режим,

   * вы также можете сделать показанный выше вызов mq_open

   * без O_NONBLOCK). Помните, что mq_setattr не может

   * использоваться для изменения значений параметров очереди

   * сообщений mq_maxmsg, mq_msgsize и других. Она может

   * использоваться только для изменения поля mq_flags в

   * структуре mq_attr. mq_flags один из O_NONBLOCK, O_RDWR и т.д.

   */

  attr.mq_flags = 0; /* set !O_NONBLOCK */

  if (mq_setattr(ds, &attr, NULL)){

    perror("mq_setattr");

    return -1;

  }

 

  /*

   * Теперь убедимся, O_NONBLOCK не установлен. Фактически,

   * эта функция также заполняет параметры очереди сообщений в

   * структуре old_addr.

   */

  if (mq_getattr(ds, &old_attr)) {

    perror("mq_getattr");

    return -1;

  }

  if (!(old_attr.mq_flags & O_NONBLOCK))

    printf("O_NONBLOCK not set\n");

 

  /*

   * Теперь принимаем сообщение из очереди. Это блокирующий вызов.

   * Приоритет принятого сообщения сохраняется в prio. Функция

   * принимает самое старое из сообщений с наивысшим приоритетом

   * из очереди сообщений. Если размер буфера, указанный аргументом

   * msg_len, меньше, чем атрибут mq_msgsize очереди сообщений,

   * вызов функции не будет успешным и вернёт ошибку.

   */

  if (mq_receive(ds, new_text, SIZE, &prio) == -1){

    perror("cannot receive");

    return -1;

  }

 

  printf("Message: %s, prio = %d\n", new_text, prio);

 

  /* Закрываем очередь... */

  if (mq_close(ds) == -1)

    perror("Closing queue error");

 

  /*

   * ...и наконец отсоединяем её. После отсоединения

   * очередь сообщений удаляется из системы.

   */

  if (mq_unlink(QUEUE_NAME) == -1)

    perror("Removing queue error");

  return 0;

}

 

Предыдущая  Содержание  Следующая