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
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 4 months ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 5 months ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 5 months ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 10 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 1 year ago
%d bloggers like this: