views:

1972

answers:

2

I plan to use Unix named pipes (mkfifo) for simple multi-process messaging. A message would be just a single line of text.

Would you discourage me from that? What obstacles should I expect?

I have noticed these limitations:

  1. A sender cannot continue until the message is received.
  2. A receiver is blocked until there are some data. Nonblocking IO would be needed when we need to stop the reading. For example, another thread could ask for that.
  3. The receiver could obtain many messages in a single read. These have to be processed before quiting.
  4. The max length of an atomic message is limited by 4096 bytes. That is the PIPE_BUF limit on Linux (see man 7 pipe).

I will implement the messaging in Python. But the obstacles hold in general.

+2  A: 
  1. Lack of portability - they are mainly a Unix thing. Sockets are more portable.
  2. Harder to scale out to multiple systems (another sockets+)
  3. On the other hand, I believe pipes are faster than sockets for processes on the same machine (less communication overhead).

As to your limitations,

  1. You can "select" on pipes, to do a non-blocking read.
  2. I normally (in perl) print out my messages on pipes seperated by "\n", and read a line from them to get one message at a time.
  3. Do be careful with the atomic length.

I find perlipc to be a good discussion between the various options, though it has perl specific code.

Todd Gardner
The readline() in a receiver will not save you from holding multiple messages in an internal buffer. They should still be processed before quiting.
Ivo Danihelka
+2  A: 

The blocking, both on the sender side and the receiver side, can be worked around via non-blocking I/O.

Further limitations of FIFOs:

  • Only one client at a time.
  • After the client closes the FIFO, the server need to re-open its endpoint.
  • Unidirectional.

I would use UNIX domain sockets instead, which have none of the above limitations.

As an added benefit, if you want to scale it to communicate between multiple machines, it's barely any change at all. For example, just take the Python documentation page on socket and replace socket.AF_INET with socket.AF_UNIX, (HOST, PORT) with filename, and it just works.

SOCK_STREAM will give you stream-like behavior; that is, two sends may be merged into one receive or vice versa. AF_UNIX also supports SOCK_DGRAM: datagrams are guaranteed to be sent and read all as one unit or not at all. (Analogously, AF_INET+SOCK_STREAM=TCP, AF_INET+SOCK_DGRAM=UDP.)

ephemient
What do you mean by "Only one client at a time"?I could have multiple writers and readers on a FIFO.
Ivo Danihelka
You have to open the FIFO for reading multiple times. Accepting new connections on the same listening socket is much cleaner.
ephemient
Just FYI, apparently on some unix platforms (Solaris) FIFOs are bidirectional.. but your point is valid. Use unix domain sockets instead.
nosatalian