什么是命名管道?

时间:2008-10-06 18:28:59

标签: sql-server pipe named-pipes

它们是什么以及它们如何运作?

上下文碰巧是SQL Server

10 个答案:

答案 0 :(得分:135)

在Windows和POSIX系统上,命名管道提供了在同一台机器上运行的进程之间进行进程间通信的方法。命名管道给你的是一种发送数据的方法,而不会涉及网络堆栈的性能损失。

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

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

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

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

答案 1 :(得分:38)

Unix和Windows都有称为“命名管道”的东西,但它们的行为不同。在Unix上,一个命名管道是一条单行道,通常只有一个读者和一个作者 - 作者写道,读者读,你得到它?

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

Unix命名管道在文件系统中显示为特殊文件,可以使用包括shell在内的普通文件IO命令进行访问。 Windows不需要,并且需要通过特殊的系统调用打开(之后它们的行为大致类似于普通的win32句柄)。

更令人困惑的是,Unix有一种称为“Unix套接字”或AF_UNIX套接字的东西,它更像(但不完全像)一个win32“命名管道”,是双向的。

答案 2 :(得分:22)

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

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

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

从命令行(man page)创建名为“myPipe”的命名管道:

mkfifo myPipe  

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

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

答案 3 :(得分:16)

根据Wikipedia

  

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

答案 4 :(得分:10)

比较

echo "test" | wc

mkdnod apipe p
wc apipe

wc将阻止

echo "test" > apipe

执行

答案 5 :(得分:5)

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

MSDN

答案 6 :(得分:5)

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

命名的管道只是一种主动挂钩到现有管道并清理其数据的方式。这是因为提供商不知道客户将吃什么数据。

答案 7 :(得分:4)

这是Technet的一个exeprt(所以不确定为什么标记的答案说命名管道更快?):

命名管道与TCP / IP套接字

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

对于命名管道,网络通信通常更具交互性。对等体不会发送数据,直到另一个对等体使用读取命令请求它。网络读取通常涉及一系列查看管道消息,然后才开始读取数据。这些在网络速度慢的情况下非常昂贵并且会导致过多的网络流量,从而影响其他网络客户端。

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

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

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

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

答案 8 :(得分:3)

unix / linux上下文中的命名管道可用于制作两个不同的shell进行通信,因为shell无法与另一个shell共享任何内容。

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

没有命名管道(或任何类型的信号量)在后台启动脚本不是问题。事情是它完成后你就无法在后台访问实例。

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

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

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

当然,您可以通过触摸触发停止来实现此目的。但是这个代码非常有趣。

答案 9 :(得分:1)

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