Manpages

名 前

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

書 式

#include <mqueue.h>

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

−lrt で リ ン ク す る 。

説 明

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

sevp 引 き 数 は sigevent 構 造 体 へ の ポ イ ン タ ー で あ る 。 こ の 構 造 体 の 定 義 と 一 般 的 な 詳 細 に つ い て は sigevent(7) を 参 照 。

sevp が NULL で な い ポ イ ン タ ー で あ れ ば 、 mq_notify() は メ ッ セ ー ジ 通 知 を 受 け 取 る よ う に 呼 び 出 し 元 の プ ロ セ ス を 登 録 す る 。 sevp が 指 す sigevent 構 造 体 の sigev_notify フ ィ ー ル ド は 、 ど の よ う な 通 知 を 行 う の か を 指 定 す る 。 こ の フ ィ ー ル ド は 以 下 の 値 の い ず れ か を 持 つ 。
SIGEV_NONE
「 空 の (null)」 の 通 知 : 呼 び 出 し 元 の プ ロ セ ス を 通 知 の 宛 先 と し て 登 録 す る が 、 実 際 に は メ ッ セ ー ジ が 到 着 し た 時 に 通 知 は 送 ら れ な い 。
SIGEV_SIGNAL

sigev_signo で 指 定 さ れ た シ グ ナ ル を 送 っ て 、 プ ロ セ ス に 通 知 す る 。 一 般 的 な 詳 細 に つ い て は sigevent(7) を 参 照 。 siginfo_t 構 造 体 の si_code フ ィ ー ル ド に は 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) を 呼 び 出 し て い る プ ロ セ ス や ス レ ッ ド に 配 送 さ れ 、 メ ッ セ ー ジ 通 知 の 登 録 は 効 力 を 持 っ た ま ま と な る 。 通 知 は 一 度 だ け 行 わ れ る 。 通 知 が 送 ら れ た 後 は 、 通 知 要 求 の 登 録 は 削 除 さ れ 、 別 の プ ロ セ ス が メ ッ セ ー ジ 通 知 を 受 信 す る よ う に 登 録 で き る よ う に な る 。 通 知 を 受 け た プ ロ セ ス が 次 の 通 知 も 受 信 し た い 場 合 は 、 mq_notify() を 使 っ て そ の 後 の 通 知 も 受 け る よ う に 要 求 す る こ と が で き る 。 mq_notify() を 再 度 呼 び 出 す の は 、 読 み 出 し て い な い メ ッ セ ー ジ を 全 部 読 み 出 し て キ ュ ー が 空 に な る 前 に す べ き で あ る (キ ュ ー か ら の メ ッ セ ー ジ 読 み 出 し を キ ュ ー が 空 に な っ た 時 に 停 止 (block) せ ず に 行 う に は 、 キ ュ ー を 非 停 止 モ ー ド (non−blocking mode) に 設 定 し て お く と よ い )。

返 り 値

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

エ ラ ー

EBADF

mqdes に 指 定 さ れ た デ ィ ス ク リ プ タ ー が 不 正 で あ る 。

EBUSY

別 の プ ロ セ ス が す で に こ の メ ッ セ ー ジ キ ュ ー に 対 す る 通 知 を 受 信 す る よ う に 登 録 し て い る 。

EINVAL

sevp−>sigev_notify が 許 可 さ れ た 値 の い ず れ で も な い 。 も し く は sevp−>sigev_notifySIGEV_SIGNAL だ が sevp−>sigev_signo が 有 効 な シ グ ナ ル 番 号 で は な い 。

ENOMEM

十 分 な メ モ リ ー が な い 。

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

準 拠

POSIX.1−2001.

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

#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)
{
struct mq_attr attr;
ssize_t nr;
void *buf;
mqd_t mqdes = *((mqd_t *) sv.sival_ptr);

/* 最 大 メ ッ セ ー ジ サ イ ズ を 決 定 し 、 メ ッ セ ー ジ 受 信 用 の バ ッ フ ァ ー を 確 保 す る
*/

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\n", nr);
free(buf);
exit(EXIT_SUCCESS); /* プ ロ セ ス を 終 了 す る */ }

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)
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)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。