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/msg
を cat
する方法もある。
各キューの詳細
ipcs -i
に msgid
を渡せばよい
$ 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
- Michael Kerrisk : The Linux Programming Interface. 2010. Ch. 45-46