Quadrat Dreieck Oval
Kreis 1 mqueue

 
Layout 4 Startseite tar Archive with source Archiv Download "all-in-one"

POSIX message queue API

The API consists of the following functions.

  • mq_open
  • mq_close
  • mq_unlink
  • mq_getattr
  • mq_setattr
  • mq_send / mq_timedsend
  • mq_receive / mq_timedreceive
  • mq_notify
With mq_notify a process can register a notification (sending a signal or starting a thread) that gets triggered if the queue goes from state empty to non empty. This is a one shot mechanism and has to be reregistered after it's occurence. When creating a queue with mq_open() you can specify how deep the queue has to be and how many bytes the biggest message can be. With mq_receive() the oldest highest priority message is received.

Userspace implementation

The message queue can be implemented on a mmap()ed file protected by some locking mechanism. Using robust locks that are released when the locking process crashes or aborted is advantageous. Otherwise the queue could be left locked.

doing it in the kernel

Since Linux version 2.6.6 the Wronski/Benedyczak implementation with further assimilation is part of the mainline kernel.
Analog to SystemV messages one could do it in kernel space.
Comparing the performance shows an advantage for the kernel version especially the more senders are involved.
Here is an archive including kernel patches for Linux 2.4 and 2.6-test, a stub library and an userspace implementation for simple performance measurements.
Another implementation from Wronski/Benedyczak is also included (3.52) You can find the separate package at their web page. The biggest differences are:
Wronski/Benedyczak (iq_send) pwaechtler (kq_send)
IOctrl syscalls
extra wait queues for priority aware wakeups normal wait queues, sorted in prio order, but not perfect
messages are stored on a heap, usage of extra slab, bigger chunks messages are stored in lists and reuse code of SystemV messages
uses more code least effort approach

A comparison made on a dual Pentium Pro system running with 200MHz. Each step transfers 1 million messages ( see simple_perf script ). When the messages are getting bigger, the iq implementation gets faster. But with a big drawback: it wants more&bigger unfragmented kernel memory.


----------------------------------------------
kq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  send:real: 0m22.53s	user: 10.190s	sys: 12.310s
  recv:real: 0m22.53s	user: 1.100s	sys: 13.280s
iq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  send:real: 0m33.44s	user: 14.490s	sys: 14.620s
  recv:real: 0m33.44s	user: 1.460s	sys: 18.700s
----------------------------------------------
kq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  recv:real: 0m17.08s	user: 1.310s	sys: 8.960s
  send:real: 0m17.08s	user: 11.650s	sys: 10.700s
iq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  recv:real: 0m37.94s	user: 2.070s	sys: 18.330s
  send:real: 0m37.94s	user: 16.580s	sys: 24.100s
----------------------------------------------
kq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  send:real: 0m18.50s	user: 11.040s	sys: 12.020s
  recv:real: 0m18.52s	user: 1.410s	sys: 11.580s
iq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 64  curmsgs: 0
  recv:real: 0m42.49s	user: 1.980s	sys: 20.070s
  send:real: 0m42.49s	user: 12.940s	sys: 18.690s
----------------------------------------------
kq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  recv:real: 0m32.74s	user: 1.440s	sys: 19.950s
  send:real: 0m32.75s	user: 14.430s	sys: 15.360s
iq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  send:real: 0m41.02s	user: 14.240s	sys: 20.280s
  recv:real: 0m41.02s	user: 1.660s	sys: 24.360s
----------------------------------------------
kq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  send:real: 0m27.77s	user: 12.870s	sys: 18.550s
  recv:real: 0m27.79s	user: 1.450s	sys: 21.230s
iq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  send:real: 0m46.28s	user: 16.120s	sys: 30.190s
----------------------------------------------
kq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  send:real: 0m28.33s	user: 12.270s	sys: 18.920s
  recv:real: 0m28.33s	user: 1.360s	sys: 23.510s
iq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 1024  curmsgs: 0
  recv:real: 0m51.09s	user: 1.850s	sys: 25.100s
  send:real: 0m51.09s	user: 13.770s	sys: 23.290s
----------------------------------------------
kq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  send:real: 2m20.01s	user: 14.180s	sys: 116.990s
  recv:real: 2m20.01s	user: 1.510s	sys: 138.530s
iq_send: 1 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  recv:real: 2m21.34s	user: 2.570s	sys: 119.930s
  send:real: 2m21.34s	user: 11.670s	sys: 129.630s
----------------------------------------------
kq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  send:real: 2m29.91s	user: 10.370s	sys: 127.820s
  recv:real: 2m29.96s	user: 1.580s	sys: 148.310s
iq_send: 2 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  send:real: 2m15.29s	user: 12.400s	sys: 118.360s
  recv:real: 2m15.32s	user: 1.830s	sys: 130.930s
----------------------------------------------
kq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  send:real: 2m36.15s	user: 11.720s	sys: 137.780s
  recv:real: 2m36.19s	user: 1.690s	sys: 154.360s
iq_send: 4 sender:flags: 0x2  maxmsg: 16  msgsize: 8192  curmsgs: 0
  send:real: 2m27.17s	user: 16.370s	sys: 122.720s
  recv:real: 2m27.20s	user: 2.010s	sys: 127.680s

 

Last Updated: Mo Aug 30 21:14:54 CEST 2004