Are Message Queues Obsolete in Linux

Are message queues obsolete in linux?

Personally I am quite fond of message queues and think they are arguably the most under-utilized IPC in the unix world. They are fast and easy to use.

A couple of thoughts:

  • Some of this is just fashion. Old things become new again. Add a shiny do-dad on message queues and they may be next year's newest and hottest thing. Look at Google's Chrome using separate processes instead of threads for its tabs. Suddenly people are thrilled that when one tab locks up it doesn't bring down the entire browser.

  • Shared memory has something of a He-man halo about it. You're not a "real" programmer if you aren't squeezing that last cycle out of the machine and MQs are marginally less efficient. For many, if not most apps, it is utter nonsense but sometimes it is hard to break a mindset once it takes hold.

  • MQs really aren't appropriate for applications with unbounded data. Stream oriented mechanisms like pipes or sockets are just easier to use for that.

  • The System V variants really have fallen out of favor. As a general rule go with POSIX versions of IPC when you can.

What is the difference between Message Queues and files in Linux. Also, what is the significance of priorities in message queues?

Files are mostly stored on the hard disk and are persistent across multiple system reboots. Message queues are stored in the main memory and are available only while the system is running and not preserved across system reboots. A file is a sequence of bytes, and by default, the system does not enforce a structure on those bytes. So, using a file for IPC is difficult, because extra logic would be required to identify messages. Also, there are problems of multiple programs writing to a file at the same time, deleting old messages, etc. Message queues are fast, because the messages are stored in the main memory. The kernel takes care of the problems like the concurrent access of a message queue by multiple processes, addition and deletion of messages. So files are used for storing information on secondary storage whereas message queues are used for inter-process communication.

What are the disadvantages of Linux's message queues?

The functions msgctl(), msgget(), msgrcv(), and msgsnd() are the 'System V IPC' message queue functions. They'll work for you, but they're fairly heavy-weight. They are standardized by POSIX.

POSIX also provides a more modern set of functions, mq_close(), mq_getattr(), mq_notify(), mq_open(), mq_receive(), mq_send(), mq_setattr(), and mq_unlink() which might be better for you (such an embarrassment of riches).

However, you will need to check which, if either, is installed on your target platforms by default. Especially in an embedded system, it could be that you have to configure them, or even get them installed because they aren't there by default (and the same might be true of shared memory and semaphores).

The primary advantage of either set of message facilities is that they are pre-debugged (probably) and therefore have concurrency issues already resolved - whereas if you're going to do it for yourself with shared memory and semaphores, you've got a lot of work to do to get to the same level of functionality.

So, (re)use when you can. If it is an option, use one of the two message queue systems rather than reinvent your own. If you eventually find that there is a performance bottleneck or something similar, then you can investigate writing your own alternatives, but until then — reuse!

POSIX message queue - Does it still exists after reboot?

On Linux, message queues are mounted on a virtual file system, and the presence of a file does not imply that anything is written to physical media. This implementation is specific to Linux and not required POSIX behaviour.

The mq_overview man page describes the implementation.

How to handle signals in Linux Message Queues (POSIX or SysV) with different sizes?

Sorry, complete rewrite, I confused the msgrcv with reading from pipes and sockets, where each packet can be read in part or as a whole.

You need to have a receiving buffer that is large enough for the largest message of all that you may receive.

The actual size is returned as the return value from msgrcv, so something like this:

 struct sig2 msg;
size_t n = msgrcv(queue_id, &msg, sizeof(msg.data), -1, 0);
if (n == -1)
{
... error - inspect errno to understand what went wrong ...
}

Note also that the default size is 16384 bytes, so a 20000 byte array may not work unless you reconfigure the default message size.



Related Topics



Leave a reply



Submit