IPC performance: Named Pipe vs Socket

2019-01-08 04:48发布

问题:

Everyone seems to say named pipes are faster than sockets IPC. How much faster are they? I would prefer to use sockets because they can do two-way communication and are very flexible but will choose speed over flexibility if it is by considerable amount.

回答1:

I would suggest you take the easy path first, carefully isolating the ipc mechanism so that you can change from socket to pipe, but I would definitely go with socket first. You should be sure IPC performance is a problem before preemptively optimizing.

And if you get in trouble because of IPC speed, I think you should consider switching to shared memory rather rather than going to pipe.

If you want to do some transfer speed testing, you should try socat, which is a very versatile program that allows you to create almost any kind of tunnel.



回答2:

I'm going to agree with shodanex, it looks like you're prematurely trying to optimize something that isn't yet problematic. Unless you know sockets are going to be a bottleneck, I'd just use them.

A lot of people who swear by named pipes find a little savings (depending on how well everything else is written), but end up with code that spends more time blocking for an IPC reply than it does doing useful work. Sure, non-blocking schemes help this, but those can be tricky. Spending years bringing old code into the modern age, I can say, the speedup is almost nil in the majority of cases I've seen.

If you really think that sockets are going to slow you down, then go out of the gate using shared memory with careful attention to how you use locks. Again, in all actuality, you might find a small speedup, but notice that you're wasting a portion of it waiting on mutual exclusion locks. I'm not going to advocate a trip to futex hell (well, not quite hell anymore in 2015, depending upon your experience).

Pound for pound, sockets are (almost) always the best way to go for user space IPC under a monolithic kernel .. and (usually) the easiest to debug and maintain.



回答3:

Keep in mind that sockets does not necessarily mean IP (and TCP or UDP). You can also use UNIX sockets (PF_UNIX), which offer a noticeable performance improvement over connecting to 127.0.0.1



回答4:

As often, numbers says more than feeling, here are some data: Pipe vs Unix Socket Performance (opendmx.net).

This benchmark shows a difference of about 12 to 15% faster speed for pipes.



回答5:

If you do not need speed, sockets are the easiest way to go!

If what you are looking at is speed, the fastest solution is shared Memory, not named pipes.



回答6:

For two way communication with named pipes:

  • If you have few processes, you can open two pipes for two directions (processA2ProcessB and processB2ProcessA)
  • If you have many processes, you can open in and out pipes for every process (processAin, processAout, processBin, processBout, processCin, processCout etc)
  • Or you can go hybrid as always :)

Named pipes are quite easy to implement.

E.g. I implemented a project in C with named pipes, thanks to standart file input-output based communication (fopen, fprintf, fscanf ...) it was so easy and clean (if that is also a consideration).

I even coded them with java (I was serializing and sending objects over them!)

Named pipes has one disadvantage:

  • they do not scale on multiple computers like sockets since they rely on filesystem (assuming shared filesystem is not an option)


回答7:

One problem with sockets is that they do not have a way to flush the buffer. There is something called the Nagle algorithm which collects all data and flushes it after 40ms. So if it is responsiveness and not bandwidth you might be better off with a pipe.

You can disable the Nagle with the socket option TCP_NODELAY but then the reading end will never receive two short messages in one single read call.

So test it, i ended up with none of this and implemented memory mapped based queues with pthread mutex and semaphore in shared memory, avoiding a lot of kernel system calls (but today they aren't very slow anymore).



回答8:

Named pipes and sockets are not functionally equivalent; sockets provide more features (they are bidirectional, for a start).

We cannot tell you which will perform better, but I strongly suspect it doesn't matter.

Unix domain sockets will do pretty much what tcp sockets will, but only on the local machine and with (perhaps a bit) lower overhead.

If a Unix socket isn't fast enough and you're transferring a lot of data, consider using shared memory between your client and server (which is a LOT more complicated to set up).

Unix and NT both have "Named pipes" but they are totally different in feature set.



回答9:

You can use lightweight solution like ZeroMQ [ zmq/0mq ]. It is very easy to use and dramatically faster then sockets.