mq_notify

Section: C Library Functions (3)
Updated: 2026-02-08
Index JM Home Page roff page
 

名前

mq_notify - メッセージ到着時に通知を行うよう登録する  

ライブラリ

リアルタイムライブラリ (librt,~-lrt)  

書式

#include <mqueue.h>
#include <signal.h>           /* Definition of SIGEV_* constants */

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

説明

mq_notify() を使うと、メッセージキューディスクリプター mqdes で参照される空のメッセージキューに新しくメッセージが到着した時に 非同期の通知 (notification) の配送が行われるように登録したり、 その解除を行ったりできる。

The sevp argument is a pointer to a sigevent structure. For the definition and general details of this structure, see sigevent(3type).

sevp が NULL でないポインターであれば、 mq_notify() はメッセージ通知を受け取るように呼び出し元のプロセスを登録する。 sevp が指す sigevent 構造体の sigev_notify フィールドは、どのような通知を行うのかを指定する。 このフィールドは以下の値のいずれかを持つ。

SIGEV_NONE
「空の (null)」の通知: 呼び出し元のプロセスを通知の宛先として登録するが、 実際にはメッセージが到着した時に通知は送られない。
SIGEV_SIGNAL
Notify the process by sending the signal specified in sigev_signo. See sigevent(3type) for general details. The si_code field of the siginfo_t structure will be set to SI_MESGQ. In addition, si_pid will be set to the PID of the process that sent the message, and si_uid will be set to the real user ID of the sending process.
SIGEV_THREAD
Upon message delivery, invoke sigev_notify_function as if it were the start function of a new thread. See sigevent(3type) for details.

一つのメッセージキューから通知を受信するように登録できるプロセスは 一つだけである。

sevp が NULL で、かつ呼び出し元のプロセスがこのメッセージキューからの 通知を受信するに現在登録している場合、登録を削除する。 これ以降、別のプロセスがこのメッセージキューから通知を受信するように 登録できるようになる。

メッセージ通知は、それまで空のキューに新しいメッセージが到着した 場合にのみ行われる。 mq_notify() が呼び出された時にそのキューが空でない場合、 そのキューが空になり、その後新しいメッセージが到着した時に 初めて通知が行われることになる。

別のプロセスやスレッドが mq_receive(3) を使って、空のキューからメッセージの読み出しを待っている場合、 メッセージ通知の登録は全て無視される。 メッセージは mq_receive(3) を呼び出しているプロセスやスレッドに配送され、 メッセージ通知の登録は効力を持ったままとなる。

通知は一度だけ行われる。通知が送られた後は、通知要求の登録は削除され、 別のプロセスがメッセージ通知を受信するように登録できるようになる。 通知を受けたプロセスが次の通知も受信したい場合は、 mq_notify() を使ってその後の通知も受けるように要求することができる。 mq_notify() を再度呼び出すのは、読み出していないメッセージを全部読み出して キューが空になる前にすべきである (キューからのメッセージ読み出しをキューが空になった時に 停止 (block) せずに行うには、キューを非停止モード (non-blocking mode) に設定しておくとよい)。  

返り値

成功すると、 mq_notify() は 0 を返す。エラーの場合、-1 を返し、 errno をエラーを示す値に設定する。  

エラー

EBADF
mqdes に指定されたメッセージキュー記述子が不正である。
EBUSY
別のプロセスがすでに このメッセージキューに対する通知を受信するように登録している。
EINVAL
sevp->sigev_notify が許可された値のいずれでもない。もしくは sevp->sigev_notify が SIGEV_SIGNAL だが sevp->sigev_signo が有効なシグナル番号ではない。
ENOMEM
十分なメモリーがない。

POSIX.1-2008 では、 sevp が NULL で、呼び出し元のプロセスがキュー mqdes に関する通知を受信するように登録されていない場合、エラー EINVAL を生成するような実装を行っても「よい」ことになっている。  

属性

この節で使用されている用語の説明については、 attributes(7) を参照。
インターフェース属性値
mq_notify() Thread safetyMT-Safe
 

VERSIONS

 

C ライブラリとカーネルの違い

In the glibc implementation, the mq_notify() library function is implemented on top of the system call of the same name. When sevp is NULL, or specifies a notification mechanism other than SIGEV_THREAD, the library function directly invokes the system call. For SIGEV_THREAD, much of the implementation resides within the library, rather than the kernel. (This is necessarily so, since the thread involved in handling the notification is one that must be managed by the C library POSIX threads implementation.) The implementation involves the use of a raw netlink(7) socket and creates a new thread for each notification that is delivered to the process.  

標準規格

POSIX.1-2008.  

歴史

POSIX.1-2001.  

例

以下のプログラムは、 コマンドライン引数で指定された名前のメッセージキューへの 通知要求を登録し、通知はスレッドの作成によって行われる。 そのスレッドは、そのキューからメッセージを一つ読み出してから、 プロセスを終了する関数を実行する。  

プログラムのソース

#include <err.h>
#include <mqueue.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

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)
        err(EXIT_FAILURE, "mq_getattr");
    buf = malloc(attr.mq_msgsize);
    if (buf == NULL)
        err(EXIT_FAILURE, "malloc");

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

    printf("Read %zd bytes from MQ\n", 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 <mq-name>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    mqdes = mq_open(argv[1], O_RDONLY);
    if (mqdes == (mqd_t) -1)
        err(EXIT_FAILURE, "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)
        err(EXIT_FAILURE, "mq_notify");

    pause();    /* Process will be terminated by thread function */
}
 

関連項目

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


 

Index

名前
ライブラリ
書式
説明
返り値
エラー
属性
VERSIONS
C ライブラリとカーネルの違い
標準規格
歴史
例
プログラムのソース
関連項目

This document was created by man2html, using the manual pages.