2 .\" Hey Emacs! This file is -*- nroff -*- source.
4 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
6 .\" Permission is granted to make and distribute verbatim copies of this
7 .\" manual provided the copyright notice and this permission notice are
8 .\" preserved on all copies.
10 .\" Permission is granted to copy and distribute modified versions of this
11 .\" manual under the conditions for verbatim copying, provided that the
12 .\" entire resulting derived work is distributed under the terms of a
13 .\" permission notice identical to this one.
15 .\" Since the Linux kernel and libraries are constantly changing, this
16 .\" manual page may be incorrect or out-of-date. The author(s) assume no
17 .\" responsibility for errors or omissions, or for damages resulting from
18 .\" the use of the information contained herein. The author(s) may not
19 .\" have taken the same level of care in the production of this manual,
20 .\" which is licensed free of charge, as they might when working
23 .\" Formatted or processed versions of this manual, if unaccompanied by
24 .\" the source, must acknowledge the copyright and authors of this work.
26 .\" Japanese Version Copyright (c) 2006 Akihiro MOTOKI all rights reserved.
27 .\" Translated 2006-07-31, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>
28 .\" Updated 2010-04-18, Akihiro MOTOKI, LDP v3.24
29 .\" Updated 2010-10-27, Akihiro Motoki, LDP v3.29
31 .TH MQ_NOTIFY 3 2010-10-04 "Linux" "Linux Programmer's Manual"
33 mq_notify \- メッセージ到着時に通知を行うよう登録する
36 .B #include <mqueue.h>
38 .BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" notification );
46 で参照される空のメッセージキューに新しくメッセージが到着した時に
47 非同期の通知 (notification) の配送が行われるように登録したり、
61 はメッセージ通知を受け取るように呼び出し元のプロセスを登録する。
67 フィールドは、どのような通知を行うのかを指定する。
71 「空の (null)」の通知: 呼び出し元のプロセスを通知の宛先として登録するが、
72 実際にはメッセージが到着した時に通知は送られない。
73 .\" When is SIGEV_NONE useful?
77 で指定されたシグナルを送って、プロセスに通知する。
87 .\" I don't know of other implementations that set
88 .\" si_pid and si_uid -- MTK
91 にはメッセージを送信したプロセスの PID が、
93 には送信プロセスの実ユーザ ID が設定される。
97 .I sigev_notify_function
98 があたかも新しいスレッドの開始関数であるかのように起動される。
103 一つのメッセージキューから通知を受信するように登録できるプロセスは
107 が NULL で、かつ呼び出し元のプロセスがこのメッセージキューからの
108 通知を受信するに現在登録している場合、登録を削除する。
109 これ以降、別のプロセスがこのメッセージキューから通知を受信するように
112 メッセージ通知は、それまで空のキューに新しいメッセージが到着した
115 が呼び出された時にそのキューが空でない場合、
116 そのキューが空になり、その後新しいメッセージが到着した時に
121 を使って、空のキューからメッセージの読み出しを待っている場合、
125 を呼び出しているプロセスやスレッドに配送され、
126 メッセージ通知の登録は効力を持ったままとなる。
128 通知は一度だけ行われる。通知が送られた後は、通知要求の登録は削除され、
129 別のプロセスがメッセージ通知を受信するように登録できるようになる。
130 通知を受けたプロセスが次の通知も受信したい場合は、
132 を使ってその後の通知も受けるように要求することができる。
134 を再度呼び出すのは、読み出していないメッセージを全部読み出して
136 (キューからのメッセージ読み出しをキューが空になった時に
137 停止 (block) せずに行うには、キューを非停止モード (non-blocking mode)
142 は 0 を返す。エラーの場合、\-1 を返し、
153 このメッセージキューに対する通知を受信するように登録している。
156 .I sevp\->sigev_notify
158 .I sevp\->sigev_notify
162 .I sevp\->sigev_signo
170 が NULL で、呼び出し元のプロセスがキュー
172 に関する通知を受信するように登録されていない場合、エラー
174 を生成するような実装を行っても「よい」ことになっている。
175 .\" Linux の実装では EINVAL は生成されない
180 コマンドライン引き数で指定された名前のメッセージキューへの
181 通知要求を登録し、通知はスレッドの作成によって行われる。
182 そのスレッドは、そのキューからメッセージを一つ読み出してから、
192 #define handle_error(msg) \\
193 do { perror(msg); exit(EXIT_FAILURE); } while (0)
195 static void /* スレッド開始関数 */
196 tfunc(union sigval sv)
201 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
204 メッセージ受信用のバッファを確保する */
206 if (mq_getattr(mqdes, &attr) == \-1)
207 handle_error("mq_getattr");
208 buf = malloc(attr.mq_msgsize);
210 handle_error("malloc");
212 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
214 handle_error("mq_receive");
216 printf("Read %ld bytes from MQ\\n", (long) nr);
218 exit(EXIT_SUCCESS); /* プロセスを終了する */
222 main(int argc, char *argv[])
228 fprintf(stderr, "Usage: %s <mq-name>\\n", argv[0]);
232 mqdes = mq_open(argv[1], O_RDONLY);
233 if (mqdes == (mqd_t) \-1)
234 handle_error("mq_open");
236 sev.sigev_notify = SIGEV_THREAD;
237 sev.sigev_notify_function = tfunc;
238 sev.sigev_notify_attributes = NULL;
239 sev.sigev_value.sival_ptr = &mqdes; /* スレッド関数に渡す引き数 */
240 if (mq_notify(mqdes, &sev) == \-1)
241 handle_error("mq_notify");
243 pause(); /* プロセスはスレッド関数により終了される */