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

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

#include

int mq_notify(mqd_t mqdes, const struct sigevent *notification);

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

Аргумент notification определяет, как именно процесс будет уведомлен. Прежде чем переходить к подробностям, стоит сделать несколько замечаний, касающихся механизма оповещения.

• Только один процесс может быть подписан на получение оповещений из определенной очереди. Если на них уже подписан другой процесс, то дальнейшие попытки подписаться завершаться неудачно (вызов mq_notify() вернет ошибку EBUSY).

• Зарегистрированный процесс оповещается только о появлении сообщения в ранее пустой очереди. Если на момент регистрации очередь уже содержит сообщения, то оповещения начнут приходить лишь после того, как она опустеет и получит новое сообщение.

• После отправки оповещения подписка процесса аннулируется, в результате чего любой другой процесс может подписаться на данную очередь. Иными словами, если процесс желает и дальше получать оповещения, то должен каждый раз заново выполнять подписку, используя вызов mq_notify().

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

• Процесс может вручную отменить подписку на оповещения из заданной очереди, вызвав функцию mq_notify() со значением NULL в качестве аргумента notification.

В подразделе 23.6.1 вы уже познакомились со структурой sigevent, которая используется в качестве типа аргумента notification. Здесь она представлена в упрощенном виде, только с теми полями, которые имеют отношение к функции mq_notify():

union sigval {

int sival_int; /* Вспомогательное целочисленное значение */

void *sival_ptr; /* Указатель на данные оповещения */

};

struct sigevent {

int sigev_notify; /* Способ оповещения */

int sigev_signo; /* Сигнал оповещения для SIGEV_SIGNAL */

union sigval sigev_value; /* Значение, передающееся в обработчик

сигнала или функцию в отдельном потоке */

void (*sigev_notify_function) (union sigval);

/* Функция, доставляющая оповещение в отдельном потоке */

void *sigev_notify_attributes; /* Указатель на 'pthread_attr_t' */

};

Поле sigev_notify этой структуры принимает одно из следующих значений.

• SIGEV_NONE — подписывает процесс на оповещения, но при появлении сообщения в ранее пустой очереди не уведомляет о данном факте. И, как обычно, после этого подписка отменяется.

• SIGEV_SIGNAL — оповещает процесс, генерируя сигнал, указанный в поле sigev_signo. Если это сигнал реального времени, то данные, передающиеся вместе с ним, указываются в поле sigev_value (см. подраздел 22.8.1). Их можно извлечь из поля si_value структуры siginfo_t, которая передается в обработчик сигнала или возвращается вызовами sigwaitinfo() или sigtimedwait(). В структуре siginfo_t также заполняются следующие поля: si_code (значение SI_MESGQ), si_signo (номер сигнала), si_pid (идентификатор процесса, пославшего сообщение) и si_uid (реальный ID пользователя, от имени которого было послано сообщение). В ряде реализаций поля si_pid и si_uid не устанавливаются.

• SIGEV_THREAD — оповещает процесс путем вызова в отдельном потоке функции, указанной в поле sigev_notify_function. Полю sigev_notify_attributes можно присвоить либо NULL, либо указатель на структуру pthread_attr_t, описывающую атрибуты нового потока (см. раздел 29.8). Объединение sigval, указанное в поле sigev_value, передается в качестве аргумента данной функции.

48.6.1. Получение оповещения в виде сигнала

В листинге 48.6 приводится пример оповещения, основанного на сигнале. Данная программа выполняет следующие шаги.

1. Открывает в неблокирующем режиме очередь сообщений, имя которой указано в командной строке , определяет значение атрибута mq_msgsize, подходящее для данной очереди , и выделяет буфер соответствующего размера, предназначенный для получения сообщения .

2. Блокирует сигнал-оповещение (SIGUSR1) и устанавливает для него обработчик .

3. Выполняет начальный вызов mq_notify(), чтобы подписать процесс на получение оповещений .

4. Входит в бесконечный цикл и в нем выполняет следующие действия:

• делает вызов sigsuspend(), который разблокирует сигнал-оповещение и ждет, пока он не будет перехвачен . Окончание данного вызова свидетельствует о появлении оповещения. На этом этапе подписка на оповещения процесса уже является недействительной;

• вызывает функцию mq_notify(), чтобы снова подписать данный процесс на оповещения ;

• выполняет цикл while, который опустошает очередь, пытаясь прочитать из нее как можно больше сообщений .

Листинг 48.6. Получение оповещения в виде сигнала

pmsg/mq_notify_sig.c

#include

#include

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

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

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

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

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

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

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

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

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