System V Message Queueの雑多なメモ

System V IPC Message Queue が使われたプログラムをメンテしている人が 2013 年現在の日本にどのくらい残っているのか知らないけど、それはともかく、System V Message Queue の雑多なメモ。

メッセージキューの統計情報

ipcs(1) コマンドに -q オプションを渡すと、SysV Message Queue の情報が表示される。
このオプションを省くと、デフォルトは Semaphore, Shared Memory, Message Queue の IPC 全表示になる。

メッセージキュー全体のサマリー

$ ipcs -q -u

------ Messages: Status --------
allocated queues = 28
used headers = 0
used space = 0 bytes

allocated queues はキューの数
used headers はメッセージの総数
used space はキューの総サイズ

各キューのサマリー

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x6e82ee5e 557056     jsmith     644        0            0
0x00000000 32769      jsmith     600        8            2
0x0000cafe 98307      jsmith     600        16384        2422

used-bytes はキュー別のメッセージ総数
messages はキュー別のメッセージ数

/proc/sysvipc/msgcat する方法もある。

各キューの詳細

ipcs -imsgid を渡せばよい

$ ipcs -q -i 32769

Message Queue msqid=32769
uid=1000        gid=1000        cuid=1000       cgid=1000       mode=0600
cbytes=8        qbytes=16384    qnum=2  lspid=25904     lrpid=0
send_time=Sat Apr  6 13:40:56 2013
rcv_time=Not set
change_time=Sat Apr  6 11:48:50 2013

重要そうな項目には以下がある

cbytes : The total number of bytes in the messages currently on the message queue.
qbytes : The maximum number of bytes allowed on the message queue.
qnum : The number of messages currently on the message queue.
lspid : The process ID of the last job to send a message to the message queue using msgsnd().
lrpid : The process ID of the last job to receive a message from the message queue using msgrcv().
send_time : The last time a msgsnd() was called using the message queue.
rcv_time : The last time a msgrcv() was called using the message queue.
change_time : The last time the entry was either created or the owner or permissions, or both, were changed.

現在の状態を出力することはできるけれども、処理したメッセージ数やバイト数といった統計情報は取得できないみたい。

SysV Message Queue の設定値

$ ipcs -lq

------ Messages Limits --------
max queues system wide = 3971
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384

max queues system wide は allocated queues の最大値
max size of message (bytes) はキューに投げるメッセージの最大バイト数。
default max size of queue (bytes) は used space の最大値

/proc/sys/kernel/ 以下で定義されている。

$ tail -n 1 /proc/sys/kernel/msg*
==> /proc/sys/kernel/msgmax <==
8192

==> /proc/sys/kernel/msgmnb <==
16384

==> /proc/sys/kernel/msgmni <==
3971

リソースの利用状況に応じて sysctl で変更すること。

キューの削除

ipcrm コマンドで行う。
key を指定する -Q オプションと、msqid を指定する -q オプションがある。

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x6e82ee5e 557056     jsmith     644        0            0
0x00000000 32769      jsmith     600        8            2
0x30efce18 589826     jsmith     644        0            0
0x0000cafe 98307      jsmith     600        16384        2422
0x00e4e92f 458756     jsmith     644        16384        16384
0x5f3868ed 622597     jsmith     644        0            0

$ ipcrm -Q 0x00e4e92f
$ ipcrm -q 557056
$ ipcs  -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x00000000 32769      jsmith     600        8            2
0x30efce18 589826     jsmith     644        0            0
0x0000cafe 98307      jsmith     600        16384        2422
0x5f3868ed 622597     jsmith     644        0            0

メッセージのパージ

不慮の事故などにより、不正なメッセージを send しちゃった時に、send 済みメッセージをバージできると便利。
残念ながら、この用途のコマンドは用意されていないみたい。
メッセージを recv するだけのプログラムを用意する必要がある。

キューの作成

ipcmk コマンドでキューを作成できる。ただし、パーミッションしか指定できず、キーはランダムに生成される。
実用的ではない。

$ ipcmk -Q -p 666
Message queue id: 753671

$ ipcs -q -i 786440

Message Queue msqid=786440
uid=1000        gid=1000        cuid=1000       cgid=1000       mode=0666
cbytes=0        qbytes=16384    qnum=0  lspid=0 lrpid=0
send_time=Not set
rcv_time=Not set
change_time=Sat Apr  6 16:52:10 2013

キュー名について

ipcs コマンドの結果を見ればわかるように、キュー名(key)は hex で表示される。
ftok でランダムなキーを生成すると、key からは何を処理するキューなのかわからないし、ftok に渡した pathname がどの key に対応しているのか確認するのも面倒。
かと言って、ftok を介さずに 0x00000010 みたいな key をつけても無愛想なだけなので、数字と a-f までを駆使して 0xadd とか 0xdead とか 0xfeed のような単語っぽい key にすると親しみが持てて良い。

ノンブロッキングにメッセージを受信

msgrcv(2)IPC_NOWAIT フラグを渡すと、メッセージをノンブロッキングに受信できる。メッセージがひとつもなければ、errno ENOMSG がセットされる。

When msgrcv() fails, errno will be set to one among the following values:

ENOMSG
IPC_NOWAIT was specified in msgflg and no message of the requested type existed on the message queue.
If insufficient space is available in the queue, then the default behavior of msgsnd() is to block until space becomes available. If IPC_NOWAIT is specified in msgflg, then the call instead fails with the error EAGAIN.

References

Leave a comment