OSDN Git Service

b1e78a556e29c4dae8350ad724032c58bc669af9
[linuxjm/LDP_man-pages.git] / release / man3 / mq_notify.3
1 '\" t
2 .\" Hey Emacs! This file is -*- nroff -*- source.
3 .\"
4 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
5 .\"
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.
9 .\"
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.
14 .\"
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
21 .\" professionally.
22 .\"
23 .\" Formatted or processed versions of this manual, if unaccompanied by
24 .\" the source, must acknowledge the copyright and authors of this work.
25 .\"
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
30 .\"
31 .TH MQ_NOTIFY 3 2010-10-04 "Linux" "Linux Programmer's Manual"
32 .SH 名前
33 mq_notify \- メッセージ到着時に通知を行うよう登録する
34 .SH 書式
35 .nf
36 .B #include <mqueue.h>
37 .sp
38 .BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" notification );
39 .fi
40 .sp
41 \fI\-lrt\fP でリンクする。
42 .SH 説明
43 .BR mq_notify ()
44 を使うと、ディスクリプタ
45 .I mqdes
46 で参照される空のメッセージキューに新しくメッセージが到着した時に
47 非同期の通知 (notification) の配送が行われるように登録したり、
48 その解除を行ったりできる。
49
50 .I sevp
51 引き数は
52 .I sigevent
53 構造体へのポインタである。
54 この構造体の定義と一般的な詳細については
55 .BR sigevent (7)
56 を参照。
57 .PP
58 .I sevp
59 が NULL でないポインタであれば、
60 .BR mq_notify ()
61 はメッセージ通知を受け取るように呼び出し元のプロセスを登録する。
62 .I sevp
63 が指す
64 .I sigevent
65 構造体の
66 .I sigev_notify
67 フィールドは、どのような通知を行うのかを指定する。
68 このフィールドは以下の値のいずれかを持つ。
69 .TP
70 .B SIGEV_NONE
71 「空の (null)」の通知: 呼び出し元のプロセスを通知の宛先として登録するが、
72 実際にはメッセージが到着した時に通知は送られない。
73 .\" When is SIGEV_NONE useful?
74 .TP
75 .B SIGEV_SIGNAL
76 .I sigev_signo
77 で指定されたシグナルを送って、プロセスに通知する。
78 一般的な詳細については
79 .BR sigevent (7)
80 を参照。
81 .I siginfo_t
82 構造体の
83 .I si_code
84 フィールドには
85 .B SI_MESGQ
86 が設定される。
87 .\" I don't know of other implementations that set
88 .\" si_pid and si_uid -- MTK
89 さらに、
90 .I si_pid
91 にはメッセージを送信したプロセスの PID が、
92 .I si_uid
93 には送信プロセスの実ユーザ ID が設定される。
94 .TP
95 .B SIGEV_THREAD
96 メッセージの配送時には、
97 .I sigev_notify_function
98 があたかも新しいスレッドの開始関数であるかのように起動される。
99 詳細は
100 .BR sigevent (7)
101 を参照。
102 .PP
103 一つのメッセージキューから通知を受信するように登録できるプロセスは
104 一つだけである。
105
106 .I sevp
107 が NULL で、かつ呼び出し元のプロセスがこのメッセージキューからの
108 通知を受信するに現在登録している場合、登録を削除する。
109 これ以降、別のプロセスがこのメッセージキューから通知を受信するように
110 登録できるようになる。
111
112 メッセージ通知は、それまで空のキューに新しいメッセージが到着した
113 場合にのみ行われる。
114 .BR mq_notify ()
115 が呼び出された時にそのキューが空でない場合、
116 そのキューが空になり、その後新しいメッセージが到着した時に
117 初めて通知が行われることになる。
118
119 別のプロセスやスレッドが
120 .BR mq_receive (3)
121 を使って、空のキューからメッセージの読み出しを待っている場合、
122 メッセージ通知の登録は全て無視される。
123 メッセージは
124 .BR mq_receive (3)
125 を呼び出しているプロセスやスレッドに配送され、
126 メッセージ通知の登録は効力を持ったままとなる。
127
128 通知は一度だけ行われる。通知が送られた後は、通知要求の登録は削除され、
129 別のプロセスがメッセージ通知を受信するように登録できるようになる。
130 通知を受けたプロセスが次の通知も受信したい場合は、
131 .BR mq_notify ()
132 を使ってその後の通知も受けるように要求することができる。
133 .BR mq_notify ()
134 を再度呼び出すのは、読み出していないメッセージを全部読み出して
135 キューが空になる前にすべきである
136 (キューからのメッセージ読み出しをキューが空になった時に
137 停止 (block) せずに行うには、キューを非停止モード (non-blocking mode)
138 に設定しておくとよい)。
139 .SH 返り値
140 成功すると、
141 .BR mq_notify ()
142 は 0 を返す。エラーの場合、\-1 を返し、
143 .I errno
144 をエラーを示す値に設定する。
145 .SH エラー
146 .TP
147 .B EBADF
148 .I mqdes
149 に指定されたディスクリプタが不正である。
150 .TP
151 .B EBUSY
152 別のプロセスがすでに
153 このメッセージキューに対する通知を受信するように登録している。
154 .TP
155 .B EINVAL
156 .I sevp\->sigev_notify
157 が許可された値のいずれでもない。もしくは
158 .I sevp\->sigev_notify
159
160 .B SIGEV_SIGNAL
161 だが
162 .I sevp\->sigev_signo
163 が有効なシグナル番号ではない。
164 .TP
165 .B ENOMEM
166 必要なメモリがなかった。
167 .PP
168 POSIX.1-2008 では、
169 .I sevp
170 が NULL で、呼び出し元のプロセスがキュー
171 .I mqdes
172 に関する通知を受信するように登録されていない場合、エラー
173 .B EINVAL
174 を生成するような実装を行っても「よい」ことになっている。
175 .\" Linux の実装では EINVAL は生成されない
176 .SH 準拠
177 POSIX.1-2001.
178 .SH 例
179 以下のプログラムは、
180 コマンドライン引き数で指定された名前のメッセージキューへの
181 通知要求を登録し、通知はスレッドの作成によって行われる。
182 そのスレッドは、そのキューからメッセージを一つ読み出してから、
183 プロセスを終了する関数を実行する。
184 .nf
185
186 #include <pthread.h>
187 #include <mqueue.h>
188 #include <stdio.h>
189 #include <stdlib.h>
190 #include <unistd.h>
191
192 #define handle_error(msg) \\
193     do { perror(msg); exit(EXIT_FAILURE); } while (0)
194
195 static void                     /* スレッド開始関数 */
196 tfunc(union sigval sv)
197 {
198     struct mq_attr attr;
199     ssize_t nr;
200     void *buf;
201     mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
202
203     /* 最大メッセージサイズを決定し、
204        メッセージ受信用のバッファを確保する */
205
206     if (mq_getattr(mqdes, &attr) == \-1)
207         handle_error("mq_getattr");
208     buf = malloc(attr.mq_msgsize);
209     if (buf == NULL)
210         handle_error("malloc");
211
212     nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
213     if (nr == \-1)
214         handle_error("mq_receive");
215
216     printf("Read %ld bytes from MQ\\n", (long) nr);
217     free(buf);
218     exit(EXIT_SUCCESS);         /* プロセスを終了する */
219 }
220
221 int
222 main(int argc, char *argv[])
223 {
224     mqd_t mqdes;
225     struct sigevent sev;
226
227     if (argc != 2) {
228         fprintf(stderr, "Usage: %s <mq-name>\\n", argv[0]);
229         exit(EXIT_FAILURE);
230     }
231
232     mqdes = mq_open(argv[1], O_RDONLY);
233     if (mqdes == (mqd_t) \-1)
234         handle_error("mq_open");
235
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");
242
243     pause();    /* プロセスはスレッド関数により終了される */
244 }
245 .fi
246 .SH 関連項目
247 .BR mq_close (3),
248 .BR mq_getattr (3),
249 .BR mq_open (3),
250 .BR mq_receive (3),
251 .BR mq_send (3),
252 .BR mq_unlink (3),
253 .BR mq_overview (7),
254 .BR sigevent (7)