Главная » 2017 » Ноябрь » 21 » man 2 mq_notify
00:58
man 2 mq_notify

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


mq_notify - включает уведомление при поступлении сообщения



ОБЗОР


#include <mqueue.h>

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

Компонуется при указании параметра -lrt.



ОПИСАНИЕ


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

Аргумент sevp является указателем на структуру sigevent. Определение и описание
структуры смотрите в sigevent(7).

Если sevp не равен null, то mq_notify() регистрирует вызывающий процесс для
получения уведомлений о сообщениях. В поле sigev_notify структуры sigevent, на
которую указывает sevp, задаётся способ выполнения уведомления. Это поле может
содержать одно из следующих значений:

SIGEV_NONE
«Нулевое» уведомление: хотя вызывающий процесс и регистрируется как
уведомляемый, при появлении сообщения уведомление не будет отправлено.

SIGEV_SIGNAL
Уведомлять процесс посредством отправки сигнала, указанного в sigev_signo.
Подробности смотрите в sigevent(7). Поле si_code структуры siginfo_t будет
изменено на SI_MESGQ. Также, значение si_pid будет изменено на PID
процесса, который посылается сообщение, а значение si_uid будет изменено
на реальный пользовательский ID посылающего процесса.

SIGEV_THREAD
При доставке сообщения вызвать sigev_notify_function, как если бы это была
начальная функция новой нити. Подробности смотрите в sigevent(7).

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

Если sevp равно NULL и вызывающий процесс уже зарегистрирован принимать сообщения
для этой очереди сообщений, то регистрация удаляется; после этого другой процесс
может зарегистрироваться для получения уведомлений о сообщениях в этой очереди.

Уведомление о сообщение возникает только при поступлении нового сообщения и если
очередь до этого была пуста. Если очередь не пуста на момент вызова mq_notify(),
то уведомление будет происходить только после опустошения очереди и поступлении
нового сообщения.

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

Уведомление выполняется один раз: после доставки уведомления регистрация удаляется
и другой процесс может зарегистрироваться для уведомления. Если уведомлённый



ОШИБКИ


EBADF В mqdes размещён некорректный дескриптор очереди сообщений.

EBUSY Другой процесс уже зарегистрировался, чтобы получать уведомление из этой
очереди сообщений.

EINVAL Значение sevp->sigev_notify содержит недопустимое значение; или
sevp->sigev_notify равно SIGEV_SIGNAL и sevp->sigev_signo не содержит
корректного номера сигнала.

ENOMEM Недостаточно памяти.

В POSIX.1-2008 сказано, что реализация может генерировать ошибку EINVAL, если sevp
равно NULL, и вызывающий ещё не зарегистрирован для получения уведомлений из
очереди mqdes.



АТРИБУТЫ


Описание терминов данного раздела смотрите в attributes(7).

┌────────────┬──────────────────────┬──────────┐
│Интерфейс │ Атрибут │ Значение │
├────────────┼──────────────────────┼──────────┤
│mq_notify() │ Безвредность в нитях │ MT-Safe │
└────────────┴──────────────────────┴──────────┘



СООТВЕТСТВИЕ СТАНДАРТАМ


POSIX.1-2001.



ЗАМЕЧАНИЯ


Отличия между библиотекой C и ядром
В glibc библиотечная функция mq_notify() реализована на основе системного вызова с
тем же именем. Если sevp равно NULL или задаёт механизм уведомления не
SIGEV_THREAD, то библиотечная функция напрямую вызывает системный вызов. Большая
часть реализации SIGEV_THREAD располагается внутри библиотеки, а не в ядре (эта
необходимость возникает из-за того, что нить, вовлечённая в обработку уведомления,
должна управляться в библиотечной реализации C нитей POSIX). В реализации
задействуется неструктурированный сокет netlink(7) и создаётся новая нить для
каждого уведомления, доставляемого процессу.



ПРИМЕР


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

Исходный код программы
#include <pthread.h>
#include <mqueue.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

static void /* начальная функция нити */
tfunc(union sigval sv)
handle_error("mq_getattr");
buf = malloc(attr.mq_msgsize);
if (buf == NULL)
handle_error("malloc");

nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
if (nr == -1)
handle_error("mq_receive");

printf("Read %zd bytes from MQ\n", nr);
free(buf);
exit(EXIT_SUCCESS); /* Завершение процесса */
}

int
main(int argc, char *argv[])
{
mqd_t mqdes;
struct sigevent sev;

if (argc != 2) {
fprintf(stderr, "Использование: %s <mq-name>\n", argv[0]);
exit(EXIT_FAILURE);
}

mqdes = mq_open(argv[1], O_RDONLY);
if (mqdes == (mqd_t) -1)
handle_error("mq_open");

sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = tfunc;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &mqdes; /* аргументы функции нити */
if (mq_notify(mqdes, &sev) == -1)
handle_error("mq_notify");

pause(); /* процесс будет завершён из функции нити */
}



СМОТРИТЕ ТАКЖЕ


mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3),
mq_overview(7), sigevent(7)



Просмотров: 355 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar