管子是什么?

它们是什么,它们是如何工作的?

上下文碰巧是 SQLServer

218522 次浏览

根据 维基百科:

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

行程间通讯(大部分)适用于 Windows 应用程序,类似于在 Unix 中使用套接字在应用程序之间进行通信。

MSDN

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

名字管道只是一种主动连接到现有管道并吸取其数据的方法。它用于提供者不知道哪些客户端会吃掉数据的情况。

命名管道是行程间通讯的 windows 系统。在 SQL 服务器的情况下,如果服务器与客户机在同一台机器上,那么可以使用命名管道传输数据,而不是 TCP/IP。

比较一下

echo "test" | wc

mkdnod apipe p
wc apipe

直到

echo "test" > apipe

执行

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

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

名叫派普斯
一个 FIFO 特殊文件。一旦创建,你可以像使用普通文件一样使用管道(打开、关闭、写入、读取等)。

从命令行(手册)创建命名管道,命名为“ myPipe”:

mkfifo myPipe

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

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

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

就像服务器监听传入请求的 IP 地址/端口一样,服务器也可以设置一个命名管道来监听请求。在这两种情况下,客户端进程(或 DB 访问库)必须知道发送请求的特定地址(或管道名称)。通常,存在一个常用的标准默认端口(与 HTTP 的端口80非常相似,SQL 服务器在 TCP/IP 中使用端口1433; 。指定管道的管道 sql 查询)。

通过设置额外的命名管道,可以运行多个 DB 服务器,每个服务器都有自己的请求侦听器。

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

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

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

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

Unix 命名管道显示为文件系统中的一个特殊文件,可以通过普通文件 IO 命令(包括 shell)访问。Windows 系统的不需要,需要用一个特殊的系统调用来打开(在此之后,它们的行为基本上就像一个普通的 win32句柄)。

更令人困惑的是,Unix 有一个叫做“ Unix socket”或 AF _ UNIX socket 的东西,它的工作原理更像(但不完全像) win32“命名管道”,是双向的。

Unix/linux 上下文中的命名管道可以用来创建两个不同的 shell 来进行通信,因为一个 shell 不能与另一个 shell 共享任何东西。

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

没有命名管道(或任何类型的信号量)在后台启动脚本不是问题。问题是当它结束的时候,你就不能在后台访问实例了。

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

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

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

当然,你有不同的方式来做到这一点,例如通过触摸触发停止。但是这个代码很漂亮,也很有趣。

这是来自 Technet 的一个例子(所以不知道为什么标记的答案说命名管道更快? ?) :

命名管道与 TCP/IP 套接字

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

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

还有一点很重要,那就是要澄清您所说的是本地管道还是网络管道。如果服务器应用程序在运行 SQLServer 实例的计算机上本地运行,则可以选择本地命名管道协议。本地命名管道以内核模式运行,速度非常快。

对于 TCP/IP 套接字,数据传输更加流畅,开销更小。数据传输还可以利用 TCP/IP Socket 性能增强机制,如窗口、延迟确认等。这在缓慢的网络中非常有用。根据应用程序的类型,这种性能差异可能非常显著。

TCP/IP Sockets 还支持一个待办事项列表队列。与在尝试连接到 SQLServer 时可能导致管道繁忙错误的命名管道相比,这可以提供有限的平滑效果。

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