什么叫管道?


Answers:


153

在Windows和POSIX系统上,命名管道都为在同一计算机上运行的进程之间进行进程间通信提供了一种方法。命名管道为您提供了一种发送数据的方式,而不会导致涉及网络堆栈的性能损失。

就像您有一个服务器在侦听IP地址/端口中的传入请求一样,服务器也可以设置一个命名管道来侦听请求。在这两种情况下,客户端进程(或数据库访问库)都必须知道发送请求的特定地址(或管道名称)。通常,存在一个常用的标准默认值(类似于HTTP的端口80,SQL Server在TCP / IP中使用端口1433; \\。\ pipe \ sql \ query用于命名管道)。

通过设置其他命名管道,您可以运行多个数据库服务器,每个服务器都有自己的请求侦听器。

命名管道的优点是通常更快,并释放网络堆栈资源。

-顺便说一句,在Windows世界中,您还可以将命名管道分配到远程计算机上-但是在这种情况下,命名管道是通过TCP / IP传输的,因此您将失去性能。使用命名管道进行本地计算机通信。


1
缺点是什么?
lindhe

2
@lindhe网络上没有自动可操作性。在实践中通常更难设置。Windows中的实现与Unix / Unix类系统中的实现不同。它们很酷,但是除非性能是必须的,否则我不会打扰。
sudo

43

Unix和Windows都有所谓的“命名管道”,但是它们的行为有所不同。在Unix上,命名管道是一条单向街道,通常只有一个读者和一个作者-作家写,而读者读,明白吗?

在Windows上,称为“命名管道”的事物是IPC对象,更像TCP套接字-事物可以双向流动并且有一些元数据(您可以在另一端获取事物的凭据,等等)。

Unix命名管道在文件系统中显示为特殊文件,并且可以使用常规文件IO命令(包括外壳程序)进行访问。Windows则不需要,并且需要通过特殊的系统调用来打开(在此之后,它们的行为通常类似于正常的win32句柄)。

更加令人困惑的是,Unix具有一种称为“ Unix套接字”或AF_UNIX套接字的东西,它的工作方式类似于(但不完全像)win32“命名管道”,是双向的。


23

Linux通过管道进行
先进先出(FIFO)进程间通信机制。

未命名的管道
在命令行上,用“ |”表示 在两个命令之间。

命名管道
FIFO特殊文件。创建管道后,您就可以像正常文件一样使用管道(打开,关闭,写入,读取等)。

要从命令行(手册页)创建一个名为“ myPipe”的命名管道:

mkfifo myPipe  

要从c创建命名管道,其中“ pathname”是您希望管道具有的名称,“ mode”包含希望管道具有的权限(手册页):

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

2
“您可以像使用普通文件一样使用管道”-并非完全正确。您既不能tell()定位也不能seek()在管道中。
纽约州

19

根据维基百科

[...]传统管道是“未命名”的,因为它匿名存在,并且仅在进程运行时才保留。命名管道是系统持久性的,并且存在于过程的生命周期之外,并且一旦不再使用它就必须“取消链接”或删除。进程通常附加到命名管道(通常显示为文件)以执行IPC(进程间通信)。


12

比较

echo "test" | wc

mkdnod apipe p
wc apipe

wc将阻止直到

echo "test" > apipe

执行


7

管道是在应用程序之间流传输数据的一种方式。在Linux下,我一直使用它来将一个进程的输出流式传输到另一个进程中。这是匿名的,因为目标应用程序不知道输入流的来源。不需要。

一个命名管道只是积极地钩住现有管道和吸尘器吸尘,其数据的方式。它用于提供者不知道哪些客户将使用数据的情况。


6

这是Technet的代表(因此不确定为什么标记的答案显示命名管道更快?):

命名管道与TCP / IP套接字

在快速局域网(LAN)环境中,传输控制协议/ Internet协议(TCP / IP)套接字和命名管道客户端在性能方面是可比的。但是,TCP / IP套接字和命名管道客户端之间的性能差异在较慢的网络(例如跨广域网(WAN)或拨号网络)中变得明显。这是因为进程间通信(IPC)机制在同级之间进行通信的方式不同。

对于命名管道,网络通信通常更具交互性。一个对等方不会发送数据,直到另一个对等方使用读取命令进行请求。网络读取通常在开始读取数据之前涉及一系列窥视的命名管道消息。这些在缓慢的网络中可能会非常昂贵,并导致过多的网络流量,进而影响其他网络客户端。

弄清楚您是在谈论本地管道还是网络管道,也很重要。如果服务器应用程序在运行SQL Server实例的计算机上本地运行,则可以使用本地命名管道协议。本地命名管道以内核模式运行,并且速度非常快。

对于TCP / IP套接字,数据传输更加简化并且开销更少。数据传输还可以利用TCP / IP套接字性能增强机制,例如窗口,延迟确认等。这在网络速度较慢的情况下非常有帮助。根据应用程序的类型,此类性能差异可能会很大。

TCP / IP套接字还支持积压队列。与命名管道相比,这只能提供有限的平滑效果,在您尝试连接到SQL Server时可能导致管道繁忙错误。

通常,TCP / IP在慢速LAN,WAN或拨号网络中是首选,而当网络速度不成问题时,命名管道可能是更好的选择,因为它提供了更多的功能,易用性和配置选项。


5

Windows应用程序的进程间通信(主要是)。类似于使用套接字在Unix中的应用程序之间进行通信。

MSDN


4
命名管道出现在1975
。– dmckee ---前主持人小猫

h!那比微软还早。据我所知,它们在Unix / Linux应用程序中很少使用。真正?

我为随机签名生成器使用了一个命名管道-由于邮件和Usenet应用程序期望一个名为$ HOME / .signature的文件具有您的签名,因此我的程序将.signature创建为一个命名管道,并向其写入随机引用。
Paul Tomblin,

3

Unix / Linux上下文中的命名管道可用于使两个不同的Shell进行通信,因为Shell根本无法与他人共享任何内容。

此外,在同一shell中实例化两次的脚本无法通过两个实例共享任何内容。在对包含start()和stop()函数的守护程序进行编码时,我发现了一种用于命名管道的方法,并且我想使用相同的脚本来执行这两个操作。

如果没有命名管道(或任何种类的信号灯),则在后台启动脚本不是问题。问题是,完成后您将无法在后台访问该实例。

因此,当您想向他发送stop命令时,您将无法执行以下操作:在没有命名管道的情况下运行同一脚本并调用stop()函数将不会执行任何操作,因为您实际上正在运行另一个实例。

解决方案是在启动守护程序时实现两个管道,一个管道读取,另一个管道写入。然后使他以及其他任务听READ管道。然后Stop()函数包含一个将在管道中写入消息的命令,该命令将由后台运行脚本处理,该脚本将执行出口0。这样,同一脚本的第二个实例仅在执行任务时:告诉第一个实例停止。

这样,只有一个脚本可以启动和停止。

当然,您可以通过多种方式来实现此目的,例如通过触摸触发停止。但这是很好的代码。


1

命名管道是用于进程间通信的Windows系统。对于SQL Server,如果服务器与客户端在同一台计算机上,则可以使用命名管道传输数据,而不是使用TCP / IP。


它不仅限于Windows,因为您的答案使它出现了。正如其他人已经指出的那样,自UNIX诞生以来,命名管道已经出现了70年代,通常看起来是一个特殊文件。无论如何都支持,但是要解决您的答案。
克里斯·查拉巴鲁克
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.