POSIXメッセージキューの使い方 その2

どーも、実装力5のおじさんです。

久々にアクセス解析を眺めていたら、”POSIX” “メッセージキュー” を絡めて検索して訪れてくれる人がそれなりにいるので、もうちょっと使い方について書いてみます。

Linuxのmqについての説明であって、他の実装のことは知りません。もしかしたら参考程度にはなるかもしれません。

使い方は man を読めばわかります。
以前まとめた POSIXメッセージキューの使い方 も参照いただければ幸いです。

スポンサーリンク

サンプルソース

まぁ、説明とか特にないのでとりあえず動いたコードを貼っておきます。
ちなみに、コードがイケてないのは私の実装力が5だからです。

共通ヘッダ common.h

キューの名前定義してるだけだからべつにいらないのでは?という意見もある。

#ifndef _COMMON_HEADER_
#define _COMMON_HEADER_
 
#define QUE_NAME "/mq"
 
#endif // _COMMON_HEADER_

mq_send側 sender.c

キューをopenして適当に hello と送りつけたあと、最後にcloseを送りつけるだけ。

#include <mqueue.h>
#include <stdio.h>
#include <unistd.h>
#include "common.h"
 
int main()
{
  int i;
  char* buff;
  mqd_t send_que;
 
  send_que = mq_open(QUE_NAME, O_WRONLY);
 
  if(-1 == send_que)
  {
    perror("mq_open error");
  }
  else
  {
    for(i=0; i<10; i++)
    {
      buff = "hello";
      printf("send msg: %s \n", buff);
 
      if(-1 == mq_send(send_que, buff, sizeof(buff), 0))
      {
        perror("error");
      }
      sleep(1);
    }
 
    buff = "close";
    printf("send msg: %s \n", buff);
    if(-1 == mq_send(send_que, buff, sizeof(buff), 0))
    {
      perror("error");
    }
  }
  return 0;
}

mq_receive側 receiver.c

受け側はキューをOpenまたは作成し、メッセージを待ちます。
stop というメッセージがきたらキューを閉じてunlinkします。

#include <mqueue.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
 
int main()
{
  int i;
  char buff[10];
  struct mq_attr attr;
  mqd_t recv_que;
 
  recv_que = mq_open(QUE_NAME, O_RDONLY|O_CREAT, 0644, NULL);
  mq_getattr(recv_que, &attr);
 
  if(-1 == recv_que)
  {
    perror("mq_open error");
  }
  else
  {
    while(1)
    {
      if(-1 == mq_receive(recv_que, buff, attr.mq_msgsize, NULL))
      {
        perror("mq_receive error");
        break;
      }
      printf("received msg: %s \n", buff);
 
      if(0 == strcmp(buff, "close"))
      {
        break;
      }
    }
  }
 
  printf("close and unlink que\n");
  mq_close(recv_que);
  mq_unlink(QUE_NAME);
 
  return 0;
}

コンパイル方法

librt をリンクする必要がある。

$gcc receiver.c -lrt -o receiver
$gcc sender.c -lrt -o sender

使い方

receiver を先に動かしてから、sender を動かす。

abstimeoutの使い方は?

また今度説明します。

実装時のはまりどころ

mq_receive で message too long エラーが返る

おそらく、size(mq_receive の 第3引数)に attr.mq_msgsize 以外の値を指定していることが原因。
mq_getattr して取れた値を使うか、キューの作成時にattrを指定しないとうまく動かない。

その他

なんかはまった経験ある人がいたら教えてください。