目次
- 前置き
- POSIXメッセージキューとは
- 最小構成(できるだけ)
- 最後に
1. 前置き
・仕事でPOSIXメッセージキューのことを知ったので実装してみようと思った
・筆者のITスキルレベルは脱初心者くらい
・Linuxの理解度は初心者に毛が生えた程度
2. POSIXメッセージキューとは
POSIXメッセージキューはUnix系OSにあるプロセス間通信をするためのライブラリの一つ。
SystemVというメッセージキューもあるらしいが、今回はPOSIXメッセージキューを実装する。以下のURLを参考にした。
POSIX メッセージキューについて調べてみた
Man page of MQ_OVERVIEW
3. 最小構成(できるだけ)
以下のコードはここから引用。引用元は私の個人利用しているgithubである。
#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;
}
#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メッセージキューのめんどくさい点を隠蔽したクラスの設計をしてみる。ちなみにエラーチェックしてないのは最小構成にするために無駄なコードを省いた結果なので、次回はエラーも考慮して実装する。