与未命名管道相比,使用命名管道有什么优势?


51

我正在审查一组由UNIX管理员提出的面试问题。我找到了一个名为“命名管道”的主题。

我搜索了这个话题;在某种程度上,我已经能够理解它:- 命名管道|| 先进先出

但是我仍然感到我缺乏何时使用这种特殊类型管道的知识。是否有未命名管道无法正常工作的特殊情况?


Answers:


39

我可以想到的命名管道(fifo)具有四个三个优点:

  • 您不必同时启动读取/写入过程
  • 您可以有多个不需要共同血统的读者/作家
  • 作为文件,您可以控制所有权和权限
  • 它们是双向的,未命名的管道可能是单向的 *

    *)认为标准壳的|管道是单向的,几发炮弹(kshzsh,和bash)也提供协进程,允许双向通信。POSIX将管道视为半双工(即,每一侧只能读取或写入),pipe()系统调用返回两个文件句柄,您可能需要将其中一个视为只读,而将另一个视为只写。某些(BSD)系统支持同时读写(POSIX禁止),而在另一些系统上则需要两个管道,每个方向一个。检查pipe()popen()并可能popen2()手册页。尽管在Linux 2.6上它是依赖的,但无方向性可能不取决于管道是否命名。

(已更新,感谢Stephane Chazelas的反馈)

因此,使用未命名管道无法立即完成的一项任务是常规的客户端/服务器应用程序。

最后(灾区)上面点一下单向管道是在Linux上,POSIX(参见相关popen())说,管道仅需读取写入,对Linux的他们是单向的。有关特定于Linux的详细信息,请参见了解Linux内核(第三版,O'Reilly)(p787)。其他操作系统提供双向(未命名)管道。

例如,Nagios将fifo用作其命令文件。各种外部进程(CGI脚本,外部检查,NRPE等)将命令/更新写入此fifo,这些由持久Nagios进程进行处理。

命名管道具有与TCP连接不同的功能,但是存在重要区别。由于fifo具有持久的文件系统名称,即使没有读取器,您也可以对其进行写操作,因此,尽管在接收方未接收到数据的情况下,您也不会丢失数据,但是写操作将被阻塞(没有异步或非阻塞的I / O)。已启动(或正在重新启动)。

作为参考,另请参见Unix域套接字,以及该Stackoverflow问题的答案,该问题总结了主要的IPC方法,并且方法讨论了popen()


2
您也可以有多个具有未命名管道的读取器/写入器。在Linux上,它们比未修饰的管道更加双向。有一个写入端和一个读取端,数据仅在一个方向上流动。在写入模式下打开fifo时,将获得写入端,在读取模式下将获得读取端,而在rw模式下,您将写入写入端并从读取中读取。这与双向管道或Unix域套接字不同,在双向管道或UNIX域套接字中,您实际上在每个方向上都有两个单独的数据流。
斯特凡Chazelas

@StephaneChazelas感谢您的反馈,我已经更新了答案,使其更加具体,并阐明了(我希望)管道和方向性。
spuratic先生

与命名管道的通信是否涉及磁盘IO?还是全部在内存中?是什么决定这些IPC机制的性能范围?
CMCDragonkai

15

未命名管道或匿名管道提供了不同进程之间一对一,单向进程间通信的方式,这些进程通过父子关系或作为提供管道的公共父级的子进程(例如外壳)而关联处理。因为进程是相关的,所以文件描述符与管道的关联可以是隐式的,并且不需要具有进程外部名称的对象。仅当使用未命名管道的进程维护该管道的打开文件描述符时,该管道才会存在。当进程退出并且OS关闭与该进程关联的所有文件描述符时,未命名管道将关闭。

命名管道实际上是FIFO。这些是由文件系统中的节点表示的持久对象。命名管道在一个或多个进程之间提供了多对多,双向通信,这些通信不一定相关,也不必同时存在。管道的文件名用作通信过程之间的地址或协定。如果只有一个进程写入命名管道,而另一个进程从命名管道读取,则命名管道的行为与两个相关进程之间的未命名管道相同。

因此,简短的答案是,您需要一个命名管道来在可能不同时存在的不相关进程之间进行通信。


+1我认为进程几乎总是同时存在的(否则管道是没有意义的-您最好将其保留在常规文件中)。这些和unix域套接字通常由守护程序服务使用,这些守护程序服务可以通过命令行来控制。如果您在/runLinux桌面系统上查看,则可能会同时找到两者(分别称为fifos和unix套接字)。这是IPC的一种形式。
goldilocks 2013年

2
@goldilocks:命名管道通常用作嵌入式系统中进程之间的驻留内存的临时邮箱,在该系统中,通信进程是短暂的,并且不会同时存在。优点是与共享内存IPC相比,实现更为简单,并且仅使用RAM。缺点是引导之间的非持久性以及管道的字节级FIFO性质与使用具有共享内存的结构的能力相比。
乔纳森·本·阿夫拉罕

@jonathan:+1,我有一些疑问:-为什么我们将命名管道称为FIFO?什么是持久对象?
Ankit 2013年

@Ankit:有人将命名管道称为FIFO,因为它的行为类似于FIFO数据结构,尤其是当打开以供单个进程进行读写时。“持久对象”是指命名管道与文件系统对象相关联。也就是说,它是一种文件类型,带有名称,并且与存储在介质上的任何其他文件具有相同的持久性。
乔纳森·本·阿夫拉罕

4

其他地方未提及的一个优点是,可以在仅文件可用的地方使用命名管道。

例如,某些电子邮件客户端具有将〜/ .signature的内容附加到每封邮件中的功能。如果.signature是命令行选项,或者邮件客户端能够注意到.signature是可执行文件并运行它,则不需要命名管道。但是,如果邮件客户端不是那么复杂,则可以创建一个名为.signature的命名管道,并运行一个应用程序,该应用程序每次读取文件时都会生成一个新的签名。


有趣。你有这样的申请吗?似乎必须在内核级别进行监视,才能了解何时访问FIFO。
通配符

4

命名管道的另一个优点是:您可以在不同的系统中使用它们。假设您希望实时交流运行在不同计算机上的两个进程。然后在这两者之间共享一个文件夹,将FIFO放在该文件夹上,然后退出。这比将旨在处理文件的应用程序转换成侦听端口的服务要容易得多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.