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

どーも、なんちゃって組み込み屋さんです。

組み込み屋さんとはいえ、Linuxが走る高性能なSoCが巷に溢れ、”プラットフォームとしてのLinux”とも無縁ではいられなくなったわけで。LinuxにおけるIPCの方法について調べる機会があったのでまとめてみました。

スポンサーリンク

POSIX メッセージキュー

Linuxにおいて、POSIX.1-2001 準拠のキューが、mq_*() 系の関数で提供されている。

くわしくは
$man mq_overview

mq_open – メッセージキューをオープンする

mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode,
                     struct mq_attr *attr);

作成/オープンに成功すると戻り値にキューディスクリプタの番号が入る。
失敗した場合は、-1 が返り、errno にエラー番号が入る。

name

name にはキューの名前が入る。
キューの名前は “/” で始まり、”/”以外の文字を最低1文字含む文字列。

oflag

oflag には、fcntl.h で定義されている制御フラグを指定する。

  • O_RDONLY – 受信専用
  • O_WRONLY – 送信専用
  • O_RDWR – 送受信

また、上記フラグと OR で以下のフラグも指定できる。

  • O_NONBLOCK – ノンブロッキングモード
  • O_CREAT – キューが存在しない場合は作成する
  • O_EXCL – O_CREAT が指定され、name を持つキューが既に存在する場合はエラーにする

mode

oflag に O_CREAT を指定した場合、追加で mode パラメータが必要となる。
mode パラメータは sys/stat.h に定義されている。
0666 のように、数字で指定することもできる。
くわしくは
$man 2 open

attr

mq_attr 構造体で、作成するキューの属性を設定できる。NULLの場合はデフォルト設定でキューが作成される。デフォルトとは、/proc/sys/fs/mqueue/* のファイルに設定されている値である。
くわしくは
$man mq_getattr

mq_send, mq_timedsend – メッセージキューにメッセージを送信する

 #include <mqueue.h>
 
int mq_send(mqd_t mqdes, const char *msg_ptr,
           size_t msg_len, unsigned int msg_prio);
#include <time.h>
#include <mqueue.h>
 
int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
                 size_t msg_len, unsigned int msg_prio,
                 const struct timespec *abs_timeout);

mqdes, *msg_ptr

mq_open で取得したディスクリプタ mqdes のキューに対して、*msg_ptr のメッセージを追加する。

msg_len

msg_ptr が指すメッセージのサイズ。なお、キューの属性 mq_msgsize 以下でなければならない。

msg_prio

メッセージの優先度を指定する値。小さいほど優先度が高い。同じ優先度を持つ場合は到着順に取り出される。

abs_timeout

タイムアウトの時間を指定することができる。タイムアウトを過ぎた場合は、エラーとして関数が返る。(NON BLOCKING mode になっていないこと前提)
タイムアウトの時刻は timespec 構造体で指定する。

struct timespec {
  time_t tv_sec;        /* 秒 */
  long   tv_nsec;       /* ナノ秒 */
};

くわしくは
$man mq_send

mq_receive, mq_timedreceive – メッセージキューからメッセージを受信する

#include <mqueue.h>
 
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,
                   size_t msg_len, unsigned int *msg_prio);
#include <time.h>
#include <mqueue.h>
 
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr,
                        size_t msg_len, unsigned int *msg_prio,
                        const struct timespec *abs_timeout);

mq_open で取得したディスクリプタ mqdes のキューからメッセージを受信し、*msg_ptrに格納する。受信したメッセージはキューから削除される。