ファイヤープロジェクト
メッセージキュー
2003-07-20T15:13+09:00   matsu
メッセージキューはパイプとより扱いが簡単でちょっと嬉しい.
メッセージキューに関する関数として,以下がある.
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);
メッセージキューの制御.メッセージキューを消したりできる.
パターンとしては,以下のようになるだろうか.
  1. msggetでメッセージキューを作成,取得する.
  2. msgsndで送信,msgrcvで受信.
  3. 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内でメッセージキューを削除するので,上の結果にはならない).
matsu(C)
Since 2002
Mail to matsu