.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (C) 2006 Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH mq_notify 3 "20 июля 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ mq_notify \- включает уведомление при поступлении сообщения .SH LIBRARY Real\-time library (\fIlibrt\fP, \fI\-lrt\fP) .SH СИНТАКСИС .nf \fB#include \fP \fB#include \fP/* Definition of SIGEV_* constants */ .PP \fBint mq_notify(mqd_t \fP\fImqdes\fP\fB, const struct sigevent *\fP\fIsevp\fP\fB);\fP .fi .SH ОПИСАНИЕ Функция \fBmq_notify\fP() позволяет вызывающему процессу регистрироваться или отменять регистрацию доставки анонимных уведомлений при появлении нового сообщения в пустой очереди сообщений, на которую ссылается дескриптор очереди сообщений \fImqdes\fP. .PP Аргумент \fIsevp\fP является указателем на структуру \fIsigevent\fP. Определение и описание структуры смотрите в \fBsigevent\fP(7). .PP Если \fIsevp\fP не равен null, то \fBmq_notify\fP() регистрирует вызывающий процесс для получения уведомлений о сообщениях. В поле \fIsigev_notify\fP структуры \fIsigevent\fP, на которую указывает \fIsevp\fP, задаётся способ выполнения уведомления. Это поле может содержать одно из следующих значений: .TP \fBSIGEV_NONE\fP .\" When is SIGEV_NONE useful? «Нулевое» уведомление: хотя вызывающий процесс и регистрируется как уведомляемый, при появлении сообщения уведомление не будет отправлено. .TP \fBSIGEV_SIGNAL\fP .\" I don't know of other implementations that set .\" si_pid and si_uid -- MTK Уведомлять процесс посредством отправки сигнала, указанного в \fIsigev_signo\fP. Подробности смотрите в \fBsigevent\fP(7). Поле \fIsi_code\fP структуры \fIsiginfo_t\fP будет изменено на \fBSI_MESGQ\fP. Также, значение \fIsi_pid\fP будет изменено на PID процесса, который посылается сообщение, а значение \fIsi_uid\fP будет изменено на реальный пользовательский ID посылающего процесса. .TP \fBSIGEV_THREAD\fP При доставке сообщения вызвать \fIsigev_notify_function\fP, как если бы это была начальная функция новой нити. Подробности смотрите в \fBsigevent\fP(7). .PP Только один процесс может быть зарегистрирован, чтобы получить уведомление из очереди сообщений. .PP Если \fIsevp\fP равно NULL и вызывающий процесс уже зарегистрирован принимать сообщения для этой очереди сообщений, то регистрация удаляется; после этого другой процесс может зарегистрироваться для получения уведомлений о сообщениях в этой очереди. .PP Уведомление о сообщение возникает только при поступлении нового сообщения и если очередь до этого была пуста. Если очередь не пуста на момент вызова \fBmq_notify\fP(), то уведомление будет происходить только после опустошения очереди и поступлении нового сообщения. .PP Если другой процесс или нить ожидают чтения сообщения из пустой очереди с помощью \fBmq_receive\fP(3), то все регистрации по уведомлению игнорируются; сообщение доставляется процесс или нити вызвавшей \fBmq_receive\fP(3), и регистрация уведомления о сообщении остаётся как была. .PP Уведомление выполняется один раз: после доставки уведомления регистрация удаляется и другой процесс может зарегистрироваться для уведомления. Если уведомлённый процесс хочет получить следующее уведомление, то он может использовать \fBmq_notify\fP() для запроса уведомления в дальнейшем. Это должно быть сделано до исчезновения всех непрочитанных сообщений из очереди (переключение очереди в неблокирующий режим полезно для опустошения очереди сообщений без блокировки, если очередь пуста). .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении \fBmq_notify\fP() возвращает 0; при ошибке возвращает \-1, а в \fIerrno\fP помещается код ошибки. .SH ОШИБКИ .TP \fBEBADF\fP В \fImqdes\fP размещён некорректный дескриптор очереди сообщений. .TP \fBEBUSY\fP Другой процесс уже зарегистрировался, чтобы получать уведомление из этой очереди сообщений. .TP \fBEINVAL\fP Значение \fIsevp\->sigev_notify\fP содержит недопустимое значение; или \fIsevp\->sigev_notify\fP равно \fBSIGEV_SIGNAL\fP и \fIsevp\->sigev_signo\fP не содержит корректного номера сигнала. .TP \fBENOMEM\fP Недостаточно памяти. .PP .\" Linux does not do this В POSIX.1\-2008 сказано, что реализация \fIможет\fP генерировать ошибку \fBEINVAL\fP, если \fIsevp\fP равно NULL, и вызывающий ещё не зарегистрирован для получения уведомлений из очереди \fImqdes\fP. .SH АТРИБУТЫ Описание терминов данного раздела смотрите в \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. Интерфейс Атрибут Значение T{ .na .nh \fBmq_notify\fP() T} Безвредность в нитях MT\-Safe .TE .sp 1 .SH ВЕРСИИ .SS "Отличия между библиотекой C и ядром" В glibc библиотечная функция \fBmq_notify\fP() реализована на основе системного вызова с тем же именем. Если \fIsevp\fP равно NULL или задаёт механизм уведомления не \fBSIGEV_THREAD\fP, то библиотечная функция напрямую вызывает системный вызов. Большая часть реализации \fBSIGEV_THREAD\fP располагается внутри библиотеки, а не в ядре (эта необходимость возникает из\-за того, что нить, вовлечённая в обработку уведомления, должна управляться в библиотечной реализации C нитей POSIX). В реализации задействуется неструктурированный сокет \fBnetlink\fP(7) и создаётся новая нить для каждого уведомления, доставляемого процессу. .SH СТАНДАРТЫ POSIX.1\-2008. .SH ИСТОРИЯ POSIX.1\-2001. .SH ПРИМЕРЫ В следующей программе показана регистрация запроса уведомления для очереди сообщений с именем, указанном в аргументе командной строки. Уведомление выполняется создаваемой нитью. Нить выполняет функцию, которая читает одно сообщение из очереди и завершает процесс. .SS "Исходный код программы" .\" SRC BEGIN (mq_notify.c) .EX #include #include #include #include #include #include \& #define handle_error(msg) \e do { perror(msg); exit(EXIT_FAILURE); } while (0) \& static void /* Thread start function */ tfunc(union sigval sv) { struct mq_attr attr; ssize_t nr; void *buf; mqd_t mqdes = *((mqd_t *) sv.sival_ptr); \& /* Determine max. msg size; allocate buffer to receive msg */ \& if (mq_getattr(mqdes, &attr) == \-1) 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\en", nr); free(buf); exit(EXIT_SUCCESS); /* Terminate the process */ } \& int main(int argc, char *argv[]) { mqd_t mqdes; struct sigevent sev; \& if (argc != 2) { fprintf(stderr, "Usage: %s \en", 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; /* Arg. to thread func. */ if (mq_notify(mqdes, &sev) == \-1) handle_error("mq_notify"); \& pause(); /* Process will be terminated by thread function */ } .EE .\" SRC END .SH "СМ. ТАКЖЕ" \fBmq_close\fP(3), \fBmq_getattr\fP(3), \fBmq_open\fP(3), \fBmq_receive\fP(3), \fBmq_send\fP(3), \fBmq_unlink\fP(3), \fBmq_overview\fP(7), \fBsigevent\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , Иван Павлов и Малянов Евгений Викторович . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .