POSIX Message Queueのキューをepollで取得

Linux 環境では Posix Message Queue仮想ファイルシステム上に作成するよう実装されており、mq_open(3) が返すメッセージ・キューディスクリプタはファイルディスクリプタでもある。

On Linux, message queues are created in a virtual file system.
http://www.kernel.org/doc/man-pages/online/pages/man7/mq_overview.7.html

実際にキューを取得待ち状態にし lsof を実行すると、キュー名でレギュラーファイルが作成されているのが確認できる。

$ ./pmsg_receive  '/mq' &
[1] 3583
$ sudo lsof -p 3583
COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
pmsg_rece 3583 jsmith  cwd    DIR  252,0     4096  916747 /home/jsmith/work/tlpi-book/pmsg
pmsg_rece 3583 jsmith  rtd    DIR  252,0     4096       2 /
pmsg_rece 3583 jsmith  txt    REG  252,0    21930  916896 /home/jsmith/work/tlpi-book/pmsg/pmsg_receive
pmsg_rece 3583 jsmith  mem    REG  252,0   135500 1440545 /lib/x86_64-linux-gnu/libpthread-2.13.so
pmsg_rece 3583 jsmith  mem    REG  252,0  1685816 1440531 /lib/x86_64-linux-gnu/libc-2.13.so
pmsg_rece 3583 jsmith  mem    REG  252,0    31752 1440547 /lib/x86_64-linux-gnu/librt-2.13.so
pmsg_rece 3583 jsmith  mem    REG  252,0   141088 1440528 /lib/x86_64-linux-gnu/ld-2.13.so
pmsg_rece 3583 jsmith    0u   CHR  136,5      0t0       8 /dev/pts/5
pmsg_rece 3583 jsmith    1u   CHR  136,5      0t0       8 /dev/pts/5
pmsg_rece 3583 jsmith    2u   CHR  136,5      0t0       8 /dev/pts/5
pmsg_rece 3583 jsmith    3r   REG   0,13       80    9441 /mq

このディスクリプタを利用してポーリングすることもできるはずと思ったら、やっぱり man にもそう書いてあった。

Polling message queue descriptors
On Linux, a message queue descriptor is actually a file descriptor, and can be monitored using select(2), poll(2), or epoll(7). This is not portable.
http://www.kernel.org/doc/man-pages/online/pages/man7/mq_overview.7.html

本当に epoll で動いてくれるか、実際に確認してみた。

Server

# pmsg_epoll.py
import select
import posix_ipc

queue_name = "/mq"
mq = posix_ipc.MessageQueue(queue_name, posix_ipc.O_CREAT)

epoll = select.epoll()
epoll.register(mq.mqd, select.EPOLLIN)

while True:
    try:
        events = epoll.poll()
        for fileno, event in events:
            print mq.receive()
    except KeyboardInterrupt:
        break

Client

# pmsg_send.py
import sys
import posix_ipc

queue_name = "/mq"
priority = 1
timeout = 10
message = sys.argv[1] if len(sys.argv) > 1 else 'test'

mq = posix_ipc.MessageQueue(queue_name)
mq.send(message = message, timeout = timeout, priority = priority)

動かす

$ python pmsg_epoll.py &
[2] 3756
$ python pmsg_send.py
('test', 1)
$ python pmsg_send.py abc
('abc', 1)

ということで、期待通りに動いてくれた。

MEMO
サンプルコードで利用した Python の posix_ipc インターフェースは $pip install posix_ipc でインストール可能

References

Advertisements
Tagged with: ,
Posted in linux, middleware

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

%d bloggers like this: