3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

POSIXメッセージキューを実装した時のメモ【最小構成編】

Last updated at Posted at 2022-04-22

目次

  1. 前置き
  2. POSIXメッセージキューとは
  3. 最小構成(できるだけ)
  4. 最後に

1. 前置き

・仕事でPOSIXメッセージキューのことを知ったので実装してみようと思った
・筆者のITスキルレベルは脱初心者くらい
・Linuxの理解度は初心者に毛が生えた程度

2. POSIXメッセージキューとは

POSIXメッセージキューはUnix系OSにあるプロセス間通信をするためのライブラリの一つ。
SystemVというメッセージキューもあるらしいが、今回はPOSIXメッセージキューを実装する。以下のURLを参考にした。
POSIX メッセージキューについて調べてみた
Man page of MQ_OVERVIEW

3. 最小構成(できるだけ)

以下のコードはここから引用。引用元は私の個人利用しているgithubである。

qsend.cpp
#include <mqueue.h>
#include <string.h>
#include <iostream>

int main(){
    const char * que_name = "/sample";
    struct mq_attr attr;
    mqd_t q;
    
    char buf[] = "hoge";

    // queue open (writeonly or create)
    q = mq_open(que_name, O_WRONLY | O_CREAT, S_IRWXU, NULL);
    
    // queue set message
    mq_send( q, (const char *)(&buf) , sizeof(buf) , 0);
    
    // if queue don't closed, can't open new queue and can't unliunk
    mq_close(q);

    // process stop
    std::cout << "please Enter" << std::endl;
    std::cin.get();

    // queue kill
    mq_unlink(que_name);

    return 0;
}
qrecv.cpp
#include <mqueue.h>
#include <string.h>
#include <iostream>

int main(){
    const char * que_name = "/sample";
    struct mq_attr attr;
    mqd_t q;
    
    char *buf;

    // queue open (readonly) 
    q = mq_open(que_name, O_RDONLY);

    // queue get setting value
    mq_getattr( q ,&attr );

    // buf size reserve
    buf = (char *)malloc(attr.mq_msgsize);
    
    // messeage get 
    mq_receive( q, (char*)buf, attr.mq_msgsize,NULL);
    
    // buf debug
    std::cout << "buf = " << buf << std::endl;
    
    // malloc release
    free(buf);

    // if queue don't closed, can't open new queue and can't unliunk
    mq_close(q);

    return 0;
}

実行結果

qsendを先に実行して、キューにメッセージを入れる。「please Enter」って書いてあるけど、enter押すとmq_unlinkするからqrecvを実行してからenterすること。分かっていると思うが、qrecvは別のコマンドプロンプト開いて実行。

~/cpp_workspace/POSIX_min$ ./qsend
please Enter
~/cpp_workspace/POSIX_min$ ./qrecv
buf = hoge

qrecvの結果を見るとhogeがちゃんと取得できている。これで2つのプロセス間通信ができていることが確認できた!

最小構成のtips集

・mq_closeするのを忘れる
忘れるとmq_openもできないし、mq_unlinkもできない。仮想環境のメモリが不足してるので、メモリリークのせいで動かなくなった(一敗)

・mq_openの第2引数(int oflag)にO_CREATを選択すると、引数4つ必要になる
Man page of MQ_OVERVIEWに書いてあるが、mq_openは引数が4つのパターンと2つのパターンがある。どうやらO_CREATがあると4つのパターンを利用する必要があるみたい。
ちなみにmq_openの第4引数である「struct mq_attr *attr」はNULLにすると、キューには初期設定がされる。初期設定のsizeは8129バイトなので、これより大きいデータを扱う場合は注意。

・mq_openで第2引数(int oflag)にO_CREATだけ選ぶとエラーを吐く
何故か作成するフラグだけだとダメらしい。どんなユースケース考えてるのかよく分からない。

・mq_sendとmq_receiveの第2引数の型変換
constの有無に注意。mq_receiveでconstを外すのは…char以外の型に変換したいから(?)

4. まとめ

今回はPOSIXメッセージキューの最小構成を構築して、実際にメッセージの送受信を確認した。

次回は構造体の送受信と、POSIXメッセージキューのめんどくさい点を隠蔽したクラスの設計をしてみる。ちなみにエラーチェックしてないのは最小構成にするために無駄なコードを省いた結果なので、次回はエラーも考慮して実装する。

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?