Читаем Linux API. Исчерпывающее руководство полностью

В этом разделе мы уделим внимание функциям, применяемым для отправки сообщений в очередь и получения их оттуда.

48.5.1. Отправка сообщений

Функция mq_send() добавляет сообщение из буфера msg_ptr в очередь сообщений, на которую ссылается дескриптор mqdes.

#include

int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,

unsigned int msg_prio);

Возвращает 0 при успешном завершении или -1 при ошибке

Аргумент msg_len обозначает длину сообщения, на которое указывает msg_ptr. Это значение не должно превышать атрибут mq_msgsize очереди; в противном случае функция mq_send() завершится ошибкой EMSGSIZE. Сообщения нулевой длины являются допустимыми.

Каждое сообщение имеет приоритет (целое положительное число), указанный в аргументе msg_prio. Сообщения в очереди размещаются в порядке убывания приоритета (наименьшим является 0). Когда в очередь добавляется новое сообщение, оно занимает место сразу за всеми сообщениями одного с ним приоритета. Если приложение не нуждается в использовании приоритетов, аргументу msg_prio можно всегда передавать значение 0.

Стандарт SUSv3 позволяет реализации определить максимально возможный приоритет; это делается либо с помощью константы MQ_PRIO_MAX, либо через значение, возвращаемое вызовом sysconf(_SC_MQ_PRIO_MAX). Стандарт SUSv3 требует, чтобы данное ограничение не было меньше 32 (_POSIX_MQ_PRIO_MAX); то есть доступны приоритеты в диапазоне как минимум от 0 до 31. Но реальный диапазон может заметно варьироваться. Например, в Linux эта константа равна 32 768, в Solaris — 32, а в Tru64 — 256.

При заполненной очереди сообщений (то есть достигнутом ограничении mq_maxmsg) дальнейшие вызовы mq_send() будут либо блокироваться, пока в очереди не освободится место, либо немедленно завершаться ошибкой EAGAIN, если был установлен флаг O_NONBLOCK.

Программа, представленная в листинге 48.4, является интерфейсом командной строки к функции mq_send(). Ее использование будет продемонстрировано в следующем разделе.

Листинг 48.4. Запись сообщения в очередь сообщений POSIX

pmsg/pmsg_send.c

#include

#include  /* Для определения O_NONBLOCK */

#include "tlpi_hdr.h"

static void

usageError(const char *progName)

{

fprintf(stderr, "Usage: %s [-n] mq-name msg [prio]\n", progName);

fprintf(stderr, " — n Use O_NONBLOCK flag\n");

exit(EXIT_FAILURE);

}

int

main(int argc, char *argv[])

{

int flags, opt;

mqd_t mqd;

unsigned int prio;

flags = O_WRONLY;

while ((opt = getopt(argc, argv, "n"))!= -1) {

switch (opt) {

case 'n': flags |= O_NONBLOCK; break;

default: usageError(argv[0]);

}

}

if (optind + 1 >= argc)

usageError(argv[0]);

mqd = mq_open(argv[optind], flags);

if (mqd == (mqd_t) -1)

errExit("mq_open");

prio = (argc > optind + 2)? atoi(argv[optind + 2]): 0;

if (mq_send(mqd, argv[optind + 1],

strlen(argv[optind + 1]), prio) == -1)

errExit("mq_send");

exit(EXIT_SUCCESS);

}

pmsg/pmsg_send.c

48.5.2. Получение сообщений

Функция mq_receive() удаляет из очереди, куда ссылается дескриптор mqdes, самое старое сообщение с наивысшим приоритетом, после чего возвращает это сообщение в буфер, на который указывает аргумент msg_ptr.

#include

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len,

unsigned int *msg_prio);

При успешном завершении возвращает количество байтов в полученном сообщении; при ошибке возвращает -1

Вызывающий процесс использует аргумент msg_len, чтобы сообщить о том, сколько байтов доступно в буфере, на который указывает msg_ptr.

Вне зависимости от реального размера сообщения аргумент msg_len (и, как следствие, размер буфера, на который указывает msg_ptr) должен быть больше или равен атрибуту очереди mq_msgsize; в противном случае mq_receive() завершится ошибкой EMSGSIZE. Если мы не знаем значение данного атрибута, то можем его получить с помощью функции mq_getattr() (в приложении, состоящем из взаимодействующих процессов, обычно можно обойтись и без этой функции, поскольку параметр mq_msgsize, как правило, устанавливается заранее).

Если аргумент msg_prio не равен NULL, то приоритет полученного сообщения копируется по адресу, на который указывает msg_prio.

При пустой очереди функция mq_receive() либо блокируется, пока не станет доступным хотя бы одно сообщение, либо сразу же завершается ошибкой EAGAIN, если был установлен флаг O_NONBLOCK (мы не увидим символ конца файла при отсутствии записывающих процессов, как это происходит при использовании каналов).

Программа из листинге 48.5, предоставляет интерфейс командной строки к функции mq_receive(). Формат команд для этой программы представлен в функции usageError().

Следующая сессия командной строки демонстрирует использование программ из листингов 48.4 и 48.5. Вначале создадим очередь и отправим в нее несколько сообщений с разными приоритетами:

$ ./pmsg_create — cx /mq

$ ./pmsg_send /mq msg-a 5

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных