Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using POSIX message queues instead of TCP sockets - how to establish "connection"?

I have client and server programs which now communicate via TCP. I'm trying out using POSIX message queues instead (in cases where the client and server are on the same machine, of course). My hope is that it will improve performance (specifically via reduced latency).

I've worked out most of it, but am not sure about one thing: how to establish the "connection." The server accepts connections from multiple clients concurrently, so I'm tempted to emulate the TCP connection establish process like so:

  1. Server opens a queue with a well-known name and reads from it continuously (it can use select(2) as with TCP).
  2. Client opens three queues: two with arbitrary names (including some uniqueness such as PID to avoid collisions), and one with the well-known name used by the server.
  3. Client posts a "connect" message to the server's queue, including the client's queue names (one is designated for client-to-server traffic and the other for the converse).
  4. Server opens the queues named in the client's connect message and begins to read (select) from the client-to-server one.
  5. Client closes the server queue with the well-known name. Two-way communication proceeds using the two queues named by the client (one for each direction).

You can probably see how this scheme is similar to the common TCP method, and that's no accident. However, I'd like to know:

  1. Can you think of a better way to do it?
  2. Do you see any potential problems with my method?
  3. Do you have any other thoughts, including about the likelihood that using message queues instead of TCP on the same machine will actually improve performance (latency)?

Keep in mind that I haven't used POSIX message queues before (I did use IBM WebSphere MQ a while back, but that's rather different). The platform is Linux.

like image 581
John Zwinck Avatar asked Jan 03 '09 22:01

John Zwinck


People also ask

What is a POSIX message queue?

POSIX message queues are a means by which processes exchange data in the form of messages to accomplish their tasks. They enable processes to synchronise their reads and writes to speed up processes. POSIX message queues are distinct from System V messages.

How do you use message queues?

To send a message, a component called a producer adds a message to the queue. The message is stored on the queue until another component called a consumer retrieves the message and does something with it. Many producers and consumers can use the queue, but each message is processed only once, by a single consumer.

How are message queues used for IPC?

IPC message queues are transient memory areas, typically provided by the underlying operating system, used for communication between clients and servers. By default, each server has its own IPC message queue on which to receive requests and replies, referred to as a Single Server, Single Queue (SSSQ).

Which is the ideal way to know all the System V message queues in the system?

The msgget system call gets the message queue identifier for the given key. The key is obtained using the ftok function. The second parameter is msg_flags. If the IPC_CREAT flag is set in msg_flags, the queue is created, if it does not already exist.


2 Answers

  1. Can you think of a better way to do it?

    Perhaps have a look at fifos (aka named pipes). They are like network sockets but for the local machine. They are uni-directional so you might need to create two, one for each direction. Your question does lack any reason of why you are making this change specifically. There is nothing wrong with using sockets for process to process communication. They are bi-directional, efficient, widely supported and do give you the freedom to separate the processes between machines later.

  2. Do you see any potential problems with my method?

    System V message queues and fifo named pipes are both absolutely fine. Fifo pipes are like regular pipes so you can read() and write() with minimal code changes. System V message queues require putting the data into a structure and invoking msgsnd(). Either approach would be fine however.

  3. Do you have any other thoughts, including about the likelihood that using message queues instead of TCP on the same machine will actually improve performance (latency)?

    My other thoughts are that as you said, you need to develop a technique so each client has a unique identifier. One approach would be to add the pid to the structure you pass across or to negotiate a unique id with the parent / master at the beginning. The other thing to note is that the benefit of System V message queues are that you listen for "selective" messages so you could ideally use one queue from the server to all the clients, with each client waiting for a different message.

    I have no idea about which technique gives you the most optimal throughput in your software. It really might not be worth using System V message queues but only you can make that decision.

Philluminati

like image 166
Philluminati Avatar answered Oct 06 '22 03:10

Philluminati


I ended up implementing it basically as I described, with a few enhancements:

  • In step 2, I used GUIDs for the queue names instead of incorporating the client's PID.
  • In step 4, I added the sending of an "accept" message from server to client.
  • When either side wishes to end communication, it sends a "disconnect" message.

The handshaking is simpler than TCP, but seems sufficient.

As for latency: it's much better. Roughly 75% less latency using POSIX message queues instead of TCP on the same machine. My messages are on the order of 100 bytes each.

like image 42
John Zwinck Avatar answered Oct 06 '22 04:10

John Zwinck