Linux 内核中的 FIFO、管道和 Unix 域套接字是同一个东西吗?

Linux 内核中的 FIFO、管道和 Unix 域套接字是同一个东西吗?

我听说 FIFO 就是命名管道。并且它们具有完全相同的语义。另一方面,我认为 Unix 域套接字与管道非常相似(尽管我从未使用过它)。所以我想知道它们是否都引用了Linux内核中的相同实现。任何想法?

答案1

UNIX 域套接字和 FIFO 可能共享其实现的某些部分,但它们在概念上有很大不同。 FIFO 在非常低的级别上运行。一个进程将字节写入管道,另一个进程从管道中读取字节。 UNIX 域套接字具有与 TCP/IP 或 UDP/IP 套接字类似的行为。

套接字是双向的,可以被许多进程同时使用。一个进程可以在同一套接字上接受多个连接并同时处理多个客户端。内核每次都会传递一个新的文件描述符connect(2)accept(2)在套接字上调用。数据包将始终进入正确的进程。
在 FIFO 上,这是不可能的。对于双向通信,您需要两个 FIFO,并且每个客户端都需要一对 FIFO。没有办法选择性地写作或阅读,因为它们是一种更为原始的交流方式。

匿名管道和 FIFO 非常相似。不同之处在于匿名管道不作为文件系统上的文件存在,因此没有进程可以open(2)这样做。它们由通过另一种方法共享它们的进程使用。如果一个进程创建管道然后执行,例如 a fork(2),它的子进程将继承其文件描述符,其中包括管道。 (命名管道/FIFO 的文件描述符也可以以相同的方式传递。)

UNIX 域套接字、匿名管道和 FIFO 的相似之处在于它们使用文件描述符提供进程间通信,其中内核处理系统调用并抽象机制。

答案2

这里有一个很好的讨论:http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos

据我所知(无论是演示幻灯片还是来源http://lxr.free-electrons.com/source/fs/pipe.c) FIFO 被实现为管道的包装器,而管道本身是通过pipefs虚拟文件系统实现的。

@lgeorget - 管道似乎使用内核内存作为读取器和写入器之间的缓冲区(而不是“共享内存”),并在用户和内核地址空间之间复制内存(例如pipe_read调用pipe_iov_copy_to_user,这又调用__copy_to_user_inatomic( 或copy_to_user)。__copy_to_user_inatomic调用copy_user_generic,这是几种 ASM 实现之一。

答案3

一个“先进先出”和一个“命名的管道”是同一件事 - 尽管它与 shell 处理命令行上两个命令之间的“管道”(|) 的方式有很大不同。

命名管道(FIFO)是由两个程序共享的单个“文件”,一个程序向其中写入,另一个程序从中读取......另一方面,套接字是两个“文件”之间的“连接” - 这可能是使用网络并位于不同的计算机上 - 一个程序读取/写入一个“文件”,另一个程序读取/写入另一个“文件”...我不认为它们有那么相似...另一方面套接字和命名管道 - 以及文件、设备、符号链接 - 都使用 inode,并且它们都实现一些常见功能(例如读取和写入)。

答案4

我的 2 美分... FIFO 和 UNIX 套接字都是双向的(类似),但套接字具有星形拓扑,而 FIFO 只是一个队列(因此​​不能相互替换),是的,它们的实现可能在内部共享代码。

**

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**

相关内容