管道,匿名管道及其命名管道的解析

管道(UNIX)
在类Unix计算机操作系统,一个管道是一个序列过程中通过其链接在一起的标准流,使每一个过程(输出标准输出)直接提供输入(标准输入)到下一个
管线标准的shell语法是列出多个命令,以竖线(在常见的UNIX空话“管道”)隔开。例如,要列出当前目录(文件LS),只保留线LS包含字符串输出“钥匙”(grep的),并查看滚动页面的搜索结果(少),用户键入以下到终端的命令行:

ls -l命令| grep的关键|少


“ls -l命令”产生的过程中,输出(stdout),其中通过管道输送到了“grep的钥匙”的过程中输入(stdin); 同样地为“少”的过程。每个进程从先前过程需要输入和用于通过下一个过程中产生的输出标准流。每个“ | ” 通过告诉到命令的标准输出的左连接到右边的命令的标准输入壳进程间通信机制被称为(匿名)管,在操作系统中实现。管道是单向的,数据流通过管道从左到右。


错误流

缺省情况下,标准错误流(“ 标准错误通过管道不会传递管道中的处理的”); 相反,它们被合并并定向到控制台。然而,许多炮弹有改变此行为的其他语法。在CSH ​​外壳,例如,使用“ |& ”而不是“ | ” 表示该标准错误流过应与标准输出合并并馈送给下道工序。在Bourne Shell中还可以合并标准错误,使用2>&1,以及其重定向到不同的文件。


Pipemill 
在最常用的简单的管道外壳连接经由管道一系列子过程,并执行每个子过程中的外部命令。因此,外壳本身被做流经管道中的数据没有直接的处理。
然而,这是可能的外壳直接执行处理,使用所谓的轧机,或pipemill(因为一,而命令用于从初始命令“磨”过的结果)。这种结构通常看起来是这样的:
命令 |  同时 阅读 VAR1 VAR2 ... ;  做
   #过程中的每行,用变量解析成VAR1 $,$ VAR2等等
   #(注意,这可能是一个子shell:VAR1,VAR2等将不可用
   #的一段时间后,循环终止;有的炮弹,比如zsh的和新
   的Korn shell的#版本,过程的命令管道的左侧
   在子shell#运营商)
   进行
按预期,如果循环体包括命令,如这样pipemill可能无法执行猫和SSH,从读标准输入:在循环的第一次迭代,这样的程序(我们称之为漏)将读取剩余从输出命令然后,循环将会终止(具有依赖于漏极的具体结果)。有几个可能的方法来避免这种行为。首先,一些水渠支持选项来禁用读取标准输入(如SSH -n)。可替代地,如果漏极并不需要从读取任何输入标准输入做一些有用的,它可以给出<的/ dev / null的作为输入。


创建管道编程
管道可以在程序控制下创建。Unix的管道() 系统调用请求操作系统,构建一个新的匿名管道对象。这导致在过程中的两个新的,打开文件描述符:管道的只读端,和只写结束。管端似乎是正常的,匿名的文件描述符,但他们没有能力争取。
为了避免死锁和利用并行,与一种或多种新的管道Unix的过程中会然后,通常,呼叫叉()来创建新的进程。然后每个进程将关闭,它不会产生或消耗任何数据之前使用管的端部(S)。可替代地,一个进程可以创建一个新的线程,并使用管在它们之间进行通信。
命名管道也可以用创建mkfifo()或用mknod(),然后表示为输入或输出文件的程序,因为它们被调用。他们允许创建多径管,并且当与标准误差重定向相结合,或者与是特别有效的发球。

执行
在大多数类Unix系统,管道的所有进程都在同一时间开始,用自己的流适当地连接,并通过管理调度与机器上运行的所有其他进程在一起。这方面的一个重要的方面,从其他管道实现设定的Unix管分开,是概念缓冲:例如发送程序可以产生5000 个字节每秒。第二,和一个接收程序可能只能够接受每秒100字节,但没有数据丢失。取而代之的是,发送程序的输出在缓冲器被保持。当接收程序准备读取数据,然后在管道下一个程序从缓冲区读取。 在Linux中,缓冲区的大小为65536字节(64KB)。一个开源的第三方过滤BFR可在需要时提供更大的缓冲区。

网络管道
像工具的netcat和socat可管道连接到TCP / IP 套接字。


匿名管道
匿名管道是一个单纯 的FIFO可用于单向通信信道间通信(IPC)。一个实现通常集成在操作系统中的文件IO子系统。通常,父程序打开匿名管道,并创建一个新的进程继承管道的另一端,或创建若干新的流程并安排他们在一个管道。

全双工(双向)的通信通常需要两个匿名管道。

下图便是例子:




在UNIX中

管道在最流行 ​​的操作系统的支持,从Unix的和DOS起,并使用在创建“ | ” 字符。

管道是许管使用所创建的管道系统调用,它创建一个新的管并返回一对文件描述符参照读和写管道的端部。


微软的Windows
像在许多其他设备的IO和IPC设施的Windows API,创建匿名管和与该特定于IO的设施API函数配置。在这种情况下CreatePipe用于创建与用于读出的单独的手柄匿名管道和写管道的端部。读写对管道的IO操作与标准IO设备的API函数进行的ReadFile和WriteFile的。

在微软的Windows,读取和写入匿名管道总是阻止。换言之,从空管读操作将导致调用线程等待,直到至少有一个字节变为可用或档案结尾收到作为管的写手柄的结果被关闭。同样,一个完整的管道上写入会导致调用线程等待,直到空间变为可用来存储写入的数据。读取可以用比所请求的字节的数(也称为较少返回短读取)。
新工艺可以继承句柄在创建过程中匿名管道。

命名管道
命名管道(也称为FIFO为它的行为)是扩展了传统的管道上的概念的Unix和类Unix系统,并且是方法之一进程间通信(IPC)。概念也在发现的OS / 2和微软视窗,尽管语义不同基本上。传统的管道是“ 无名 ”,只有持续的时间的过程。命名管道,但是,可以作为系统启动,超出了进程的生命持续的时间。它可以如果不再使用被删除。通常命名管道显示为一个文件,一般流程附加到它的进程间通信。
在Unix中

取而代之的是传统的,无名的,外壳管道,一个名为管道使用了文件系统。它是使用显式地创建mkfifo子()或用mknod() ,以及两个独立的过程可以通过名称访问该管-一个进程可以打开它作为读取器,和其他作为作家。


在Windows 

命名管道可以很像一个文件访问。Win32的 SDK函数的CreateFile,ReadFile的,WriteFile的和CloseHandle的打开,读取,分别写入和关闭管道。不像Unix中,有没有命令行界面。
命名管道不能安装一个正常的文件系统中,在不同的Unix。也不像它们在Unix上,命名管道是挥发性的,(他们的最后一个引用被关闭后删除)。每一个管放置在命名管道文件系统(NPFS),安装在特殊路径下的根目录\\。(也就是,一个名为“管道富 ”将有一个全路径名\\。)。在流水线使用匿名管道实际上是一个名为一个随机命名的管道。
它们很少被用户看到的,但也有明显的例外。在VMware工作站 PC硬件的虚拟化工具,例如,可以公开仿真串行端口到主机系统的命名管道和WinDbg的内核模式的调试器从微软支持命名管道作为调试会话(实际上是一个交通工具,VMware和WinDbg中可以耦合在一起-因为WinDbg中通常需要到目标计算机的串行连接-让司机 开发商做他们的一台计算机上开发和测试)。这两个方案都需要用户在输入姓名\\。\管道\ 名称形式。

Windows NT的命名管道可以继承的安全上下文。

在Microsoft Windows命名管道的总结:
   机器间和计算机内部IPC
  半双工或全双工
  面向字节或面向消息 ​​的
  可靠
  阻塞或非阻塞读取和写入
  标准设备I / O句柄(FILEREAD,FILEWRITE)
  命名空间用来创建手柄
  低效WAN流量(显式数据传输请求,不像例如TCP / IP滑动窗口等)

  Peekable读(读不受管的输入缓冲器中移除)


在.NET框架 3.5增加了命名管道支持。


命名管道也可以用来作为在一个端点的Microsoft SQL Server。


命名管道也是在一个网络协议服务器消息块(SMB)套件的基础上,利用一个特殊的进程间通信(IPC)的份额。SMB的IPC可以无缝透明地传递用户的认证范围内跨命名管道。Windows NT的的整个NT域服务的协议套件作为实施DCE / RPC服务通过命名管道,因为是在Exchange 5.5管理应用程序。


最后,再给大家看看mkfifo()或用mknod()的用法


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值