名 前
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_notify が SIGEV_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/ に 書 か れ て い る 。