I heard that FIFOs are named pipes. And they have exactly the same semantics. On the other hand, I think Unix domain socket is quite similar to pipe (although I've never made use of it). So I wonder if they all refer to the same implementation in Linux kernel. Any idea?
-
From the answer below I realized my question is sort of ambiguous and it's hard to be answered. It's likely no one could know so many details of implementational stuff in the kernel (even for kernel developers). If someone can confirm that Unix domain socket, pipe and FIFO they all buffer the data being sent in shared memory under Linux, my question is solved. Well... partly solved.– JustinCommented May 15, 2013 at 14:13
-
FIFO = named pipes != pipes. FIFOs can be bidirectional like a socket pair. Regular pipes are unidirectional. All have the file interface and file semantics. Why does implementation matter to you?– Petr SkocikCommented Oct 21, 2015 at 21:02
-
I know pipes are circular buffers, and that with the STREAMS system, these can have shared implementation, however Linux doesn't use STREAMS by default. I believe Linux hardcodes these IPC channels. I don't feel like checking, though. :D Why don't you? The code is publicly available.– Petr SkocikCommented Oct 21, 2015 at 21:04
-
If they all share the same implementation, their efficiency should be close to each other. And, to me, kernel code is too hard to understand.– JustinCommented Oct 25, 2015 at 12:59
5 Answers
UNIX domain sockets and FIFO may share some part of their implementation but they are conceptually very different. FIFO functions at a very low level. One process writes bytes into the pipe and another one reads from it. A UNIX domain socket has similar behaviour as a TCP/IP or UDP/IP socket.
A socket is bidirectional and can be used by a lot of processes simultaneously. A process can accept many connections on the same socket and attend several clients simultaneously. The kernel delivers a new file descriptor each time connect(2)
or accept(2)
is called on the socket. The packets will always go to the right process.
On a FIFO, this would be impossible. For bidirectional communication, you need two FIFOs, and you need a pair of FIFOs for each of your clients. There is no way of writing or reading in a selective way, because they are a much more primitive way to communicate.
Anonymous pipes and FIFOs are very similar. The difference is that anonymous pipes don't exist as files on the filesystem so no process can open(2)
it. They are used by processes that share them by another method. If a process creates pipes and then performs, for example, a fork(2)
, its child will inherit its file descriptors and, among them, the pipe. (File descriptors to named pipes/FIFOs can also be passed in the same way.)
The UNIX domain sockets, anonymous pipes and FIFOs are similar in the fact they provide interprocess communication using file descriptors, where the kernel handles the system calls and abstracts the mechanism.
-
"UNIX domain sockets and FIFO may share some part of their implementation" ... the point is "some part of" ... I just realized my question is sort of ambiguous and it's hard to be answered. It's likely no one could know so many details of what parts they share in the kernel (even for kernel developers). Nevertheless... could anyone confirm that Unix domain socket, pipe and FIFO they all buffer the data being sent in shared memory under Linux? If it's confirmed, my question is solved. Well... partly solved.– JustinCommented May 15, 2013 at 14:09
-
Well, yes, there is a buffer managed by the kernel. For example, with FIFOs, yoou can kill the writer and the reader can still what was sent into the pipe before the death of the writer. With sockets, it's a bit more complicated because they function with a connected protocol. But if you send, say, an int to the socket, and then get out of scope so that the int is cleared from the sender stack, the receiver can still read it. So, there is clearly a buffer somewhere.– lgeorgetCommented May 15, 2013 at 14:23
-
Re-reading the comment, not sure I'm clear here... Let me know if there still is something unclear.– lgeorgetCommented May 15, 2013 at 14:29
-
-
There is also the
socketpair()
function that returns a pair of mutually connected sockets without any listener being established. Commented Sep 29, 2021 at 19:14
There's quite a good discussion of this here: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
So far as I can see (both from the presentation slides, and the source at http://lxr.free-electrons.com/source/fs/pipe.c) FIFOs are implemented as wrappers around pipes, while pipes themselves are implemented via the pipefs
virtual filesystem.
@lgeorget - The pipes appear to use kernel memory for the buffers between the readers and the writers (as opposed to 'shared memory') and copy memory between user and kernel address spaces (e.g. pipe_read
calls pipe_iov_copy_to_user
, which in turn calls __copy_to_user_inatomic
(or copy_to_user
). __copy_to_user_inatomic
calls copy_user_generic
, which is one of several ASM implementations.
A "FIFO" and a "named pipe" is the same thing - though it's quite different from how a shell handles a "pipe" (|) between two commands on the command-line.
A named pipe (FIFO) is a single "file" shared by two programs, where one writes to it and the other read from it... A socket on the other hand is a "connection" between two "files" - which may use a network and be on separate computers - where one program read/writes to one "file" and another program read/writes to the other... I don't think they're that similar... On the other hand both sockets and named pipes - as well as files, devices, symbolic links - all uses inodes, and they all implements some common features (like read and write).
-
1Yes, Unix domain socket is kind of socket, so it's API is similar to other socket APIs such as TCP or UDP, etc. However, Unix domain socket can only be used as "local" IPC. And the way it transfers data is in first in first out manner, pretty much like FIFO & pipe. So I think it's possible Unix domain socket's API is just another encapsulation of identical implementation so we use it as if it were a socket. I think it's possible they all share the same internal in the kernel ... I want to confirm if it's true or not.– JustinCommented May 15, 2013 at 12:49
-
what does that '"connection" between two "files"' even mean?– ilkkachuCommented Sep 30, 2021 at 8:01
-
For named pipes (FIFO), two processes shares one file - one process writes to the FIFO, and the other reads from it. For a socket, the processes got one "file" ("Everything is a file") each, and a connection is established between them - which of course really happens through network ports. That said, I'm amazed that you with your stellar reputation, bothered to down-vote my answer and leave a rhetoric comment, when you could just as easily have edited and improved my answer - or written a better answer yourself! Commented Oct 2, 2021 at 6:49
I don't think so Justin. If I'm not mistaken, and I quite possibly am, I think FIFOs use a file on disk, and Unix Domain sockets use kernel memory.
Also, as an addition to the poster above who mentioned that Unix domain sockets are bi-directional, that is only the case when using a SOCK_STREAM socket. SOCK_DGRAM Unix domain sockets are, in fact, uni-directional, and can only send() from the code that called connect(), to the code that called bind().
Of course, the code that called connect() must also call bind() to create it's own endpoint, but that has nothing to do with your question.
-
5Welcome on StackExchange, and thank you for posting. A few remarks... 1) If you're "quite possibly" mistaken, you should double-check before answering ; this site is not a forum nor a chat. 2) Thank you for your precision on datagram oriented sockets 3 ) There is no need to post something that has "nothing to do" with the question. :)– lgeorgetCommented Jul 2, 2013 at 20:51
-
I can't find anything in the man pages to support the statement that unix domain datagram sockets are unidirectional. You should be able to call
sendto()
andrecvfrom()
with them just like with UDP sockets, even withoutconnect()
ing. (I think you need tobind()
, though.) That's what e.g.UNIX-SENDTO:/tmp/foo1.sock,bind=/tmp/foo2.sock
withsocat
seems to do.– ilkkachuCommented Sep 30, 2021 at 8:08
My 2 cents...FIFO and UNIX socket are both bi-directional (similar) but socket have a star topology while a FIFO is just a queue (and hence cannot replace each other), yes their implementation may share code internally.
**
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR); //so that you can read/write to it
...
write(fd, buff1, sizeof(buff1));
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1)); //read that something**
-
-
FIFOs are not bi-directional, they're one way pipes (FIFO queue is their general name outside of *nix terminology).– ocodoCommented Jul 5, 2022 at 4:46