我听说FIFO被称为管道。它们具有完全相同的语义。另一方面,我认为Unix域套接字与管道非常相似(尽管我从未使用过)。因此,我想知道它们是否都引用Linux内核中的同一实现。任何的想法?
我听说FIFO被称为管道。它们具有完全相同的语义。另一方面,我认为Unix域套接字与管道非常相似(尽管我从未使用过)。因此,我想知道它们是否都引用Linux内核中的同一实现。任何的想法?
Answers:
UNIX域套接字和FIFO可以共享其实现的某些部分,但是它们在概念上是非常不同的。FIFO的功能很低。一个进程将字节写入管道,另一个进程从中读取字节。UNIX域套接字具有与TCP / IP套接字相同的行为。
套接字是双向的,可以同时被许多进程使用。一个进程可以在同一套接字上接受许多连接,并同时参与多个客户端。内核每次都会提供一个新的文件描述符,connect(2)
或者accept(2)
在套接字上调用它。数据包将始终进行正确的处理。
在FIFO上,这是不可能的。对于双向通信,您需要两个FIFO,并且每个客户都需要一对FIFO。没有选择性的书写或阅读方法,因为它们是一种更为原始的交流方式。
匿名管道和FIFO非常相似。区别在于,匿名管道不作为文件系统上的文件存在,因此没有进程可以处理open(2)
。由其他方法共享它们的进程使用它们。如果某个进程打开一个FIFO,然后执行例如a fork(2)
,则其子进程将继承其文件描述符,并在其中包括管道。
UNIX域套接字,匿名管道和FIFO在使用共享内存段方面是相似的。实现的细节可能因一个系统而异,但是思想始终是相同的:在两个不同的进程中将相同的内存部分附加到内存映射中,以使它们共享数据
(编辑:这是一种实现它的明显方式,但是而不是在Linux中的实际操作,Linux仅使用内核内存作为缓冲区,请参见下面的@ tjb63回答)。
然后内核处理系统调用并抽象化该机制。
这里对此进行了很好的讨论: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实现的。
“ FIFO”和“ 命名管道”是同一件事-尽管它与shell在命令行上的两个命令之间处理“管道”(|)的方式完全不同。
命名管道(FIFO)是由两个程序共享的单个“文件”,其中一个程序对其进行写入,另一个程序则从该文件中读取...另一方面,套接字是两个“文件”之间的“连接”,这可能使用网络并位于单独的计算机上-其中一个程序读取/写入一个“文件”,另一个程序读取/写入另一个“文件” ...我不认为它们是如此相似...另一方面套接字和命名管道-以及文件,设备,符号链接-均使用inode,并且它们都实现了一些通用功能(例如读取和写入)。
我不认为贾斯汀。如果我没记错的话,很可能是这样,我认为FIFO使用磁盘上的文件,而Unix Domain套接字使用内核内存。
另外,除了上面提到的Unix域套接字是双向的,还包括使用SOCK_STREAM套接字的情况。SOCK_DGRAM实际上,Unix域套接字是单向的,并且只能从调用connect()的代码发送到调用bind()的代码。
当然,调用connect()的代码也必须调用bind()来创建自己的端点,但这与您的问题无关。
我的2 cents ... 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**