メッセージキュー
メッセージキューはパイプとより扱いが簡単でちょっと嬉しい.
メッセージキューに関する関数として,以下がある.
- int msgget(key_t key, int msgflg);
- 指定したkeyのメッセージキュー識別子を取得.msgflgにはパーミッションやオプションなどを指定する.これにIPC_CREATを指定すると,指定したkeyのメッセージキューがない場合は作成してくれる.
- int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
- メッセージの送信.
- ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);
- メッセージの受信.
- int msgctl(int msqid, int cmd, struct msqid_ds *buf);
- メッセージキューの制御.メッセージキューを消したりできる.
- msggetでメッセージキューを作成,取得する.
- msgsndで送信,msgrcvで受信.
- msgctlでメッセージキューを削除する.
以上を踏まえてサンプルを示す.まず送信側.
そして受信側.
メッセージは構造体を介して送受信する.この構造体はサンプルのmsgbufのように最初のフィールドをlong int型にしてメッセージタイプ(正の整数)を指定する.サンプルの送信側mq-sndでは引数にこのメッセージタイプとメッセージ文字列を引数に渡す.
$ ./mq-snd 2 type2 $ ./mq-snd 3 type3 $ ./mq-snd 1 type1メッセージキューが一杯だと,メッセージキューに空きがでるまで待たされる.ノンブロッキンブモードにするには,msgsndのmsgflgにIPC_NOWAITを指定する.サンプルの受信側mq-rcvでは,受信するメッセージタイプを引数に渡す.
$ ./mq-rcv -2 received message: type2 received message: type1あらかじめ先のmq-sndを実行していた場合の結果である.上の様に負の数を渡すと,そのタイプの値以下のメッセージをキューから取り出す.取り出されなかったメッセージはキューに残っている.
$ ./mq-rcv 0 received message: type3この様にtypeに0を指定するとすべてのtypeがマッチする(注:mq-sndで文字列exitを送信してmq-rcvを終了すると,mq-rcv内でメッセージキューを削除するので,上の結果にはならない).

