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

$ ./pmsg_send /mq msg-b 0

$ ./pmsg_send /mq msg-c 10

Затем последовательно выполним несколько команд, чтобы извлечь эти сообщения из очереди:

$ ./pmsg_receive /mq

Read 5 bytes; priority = 10

msg-c

$ ./pmsg_receive /mq

Read 5 bytes; priority = 5

msg-a

$ ./pmsg_receive /mq

Read 5 bytes; priority = 0

msg-b

Как видно из вывода, приведенного выше, сообщения были извлечены в порядке их приоритета.

На этот момент очередь является пустой. Если выполнить еще одно блокирующее извлечение, то операция будет приостановлена:

$ ./pmsg_receive /mq

Блокируется; чтобы завершить программу, нажимаем Ctrl+C

С другой стороны, если выполнить неблокирующее извлечение, то вызов немедленно вернет сообщение об ошибке:

$ ./pmsg_receive — n /mq

ERROR [EAGAIN/EWOULDBLOCK Resource temporarily unavailable] mq_receive

Листинг 48.5. Чтение сообщений из очереди POSIX

pmsg/pmsg_receive.c

#include

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

#include "tlpi_hdr.h"

static void

usageError(const char *progName)

{

fprintf(stderr, "Usage: %s [-n] mq-name\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;

void *buffer;

struct mq_attr attr;

ssize_t numRead;

flags = O_RDONLY;

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

switch (opt) {

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

default: usageError(argv[0]);

}

}

if (optind >= argc)

usageError(argv[0]);

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

if (mqd == (mqd_t) -1)

errExit("mq_open");

if (mq_getattr(mqd, &attr) == -1)

errExit("mq_getattr");

buffer = malloc(attr.mq_msgsize);

if (buffer == NULL)

errExit("malloc");

numRead = mq_receive(mqd, buffer, attr.mq_msgsize, &prio);

if (numRead == -1)

errExit("mq_receive");

printf("Read %ld bytes; priority = %u\n", (long) numRead, prio);

if (write(STDOUT_FILENO, buffer, numRead) == -1)

errExit("write");

write(STDOUT_FILENO, "\n", 1);

exit(EXIT_SUCCESS);

}

pmsg/pmsg_receive.c

48.5.3. Отправка и получение сообщений с ограниченным временем ожидания

Функции mq_timedsend() и mq_timedreceive() являются прямыми аналогами mq_send() и mq_receive(), но с одним отличием: если операция не может быть выполнена немедленно и если среди атрибутов сообщения не указан флаг O_NONBLOCK, аргумент abs_timeout определяет продолжительность блокирования вызова.

#define _XOPEN_SOURCE 600

#include

#include

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

unsigned int msg_prio, const struct timespec *abs_timeout);

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

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

unsigned int *msg_prio,

const struct timespec *abs_timeout);

Возвращает объем полученного сообщения (в байтах) или -1 при ошибке

Аргумент abs_timeout представляет собой структуру timespec (см. подраздел 23.4.2), которая задает время ожидания в виде количества секунд и наносекунд, прошедших с начала «эры UNIX». Для указания относительного времени ожидания можно воспользоваться функцией clock_gettime(), чтобы извлечь текущее значение часов CLOCK_REALTIME и затем добавить к нему необходимый период времени, получив тем самым структуру timespec, инициализированную должным образом.

Если вызов функции mq_timedsend() или mq_timedreceive() не завершается вовремя, то он возвращает ошибку ETIMEDOUT. Если в Linux аргументу abs_timeout присвоить значение NULL, то время ожидания будет неограниченным. Однако такая возможность не предусмотрена стандартом SUSv3, и портируемые приложения не могут на нее полагаться.

Функции mq_timedsend() и mq_timedreceive() изначально появились в стандарте POSIX.1d (1999) и доступны не во всех реализациях UNIX.

48.6. Оповещение о сообщении

Особенность, которая отличает очереди сообщений POSIX от их аналогов из System V, состоит в возможности получать асинхронные оповещения о появлении в ранее пустой очереди нового сообщения (то есть очередь перестает быть пустой). Это значит, что вместо выполнения блокирующего вызова mq_receive() или маркировки дескриптора очереди сообщений как неблокирующего с последующими регулярными «опросами» очереди процесс может подписаться на оповещения о приходе сообщений и заняться чем-нибудь другим. Оповещение можно получать либо в виде сигнала, либо путем вызова функции в отдельном потоке.

Оповещения, предоставляемые очередями сообщений POSIX, похожи на механизм оповещений для POSIX-таймеров, описанный в разделе 23.6 (оба этих программных интерфейса изначально появились в стандарте POSIX.1b).

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

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

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

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

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

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

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

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

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