Unix管道的确切知识是什么


52

我听说过道格拉斯·麦克罗伊(Douglas Mcllroy)如何提出这个概念以及肯·汤普森(Ken Thompson)如何在一夜之间实现这个故事。

据我了解,管道是一个系统调用,它在两个进程之间共享一块内存,一个进程在其中写入数据,其他进程从中读取数据。

作为不熟悉OS内部或概念的人,我想知道故事中的“天才”到底是什么?这是两个进程共享内存的想法吗?还是执行?或两者?

PS:我知道管道的用途或如何在外壳中使用它。问题是关于|


4
我想在早期,大力推动实现一种组成应用程序的机制是非常激进的。为此,您需要具有将接口与实现分离的良好格式的概念,并实现功能组合在编程中的实用性。
Chan-Ho Suh 2015年

4
不仅如此,应用程序在运行时已经具有标准输入句柄和标准输出句柄,而类似Unix的操作系统API具有读取/写入功能以应用于这些句柄。巧妙地使用一些正交且功能强大的概念(句柄,它们的输出和输入)不仅会导致管道,还会导致套接字,字符设备交互以及许多其他事情。现在我们有了文件句柄(用于提供键盘输入和文本输出的tty),让我们编写应用程序,以便一个应用程序成为另一个应用程序的tty。
沃伦·P

6
@WarrenP实际上,得到的Unix标准输入和标准输出,因为pipe()系统调用和|壳操作者(参照麦克罗伊)。或者,正如伏尔泰可能曾说过的:“ 如果[stdio]不存在,则有必要发明[它]。 ” :-)
Ross Patterson

在没有AFTER管道之前,没有文件句柄,进出句柄之类的东西吗?
沃伦·P

4
@WarrenP:听起来就像帕特森所说的是:首先有文件句柄。然后,这些家伙提出了这样的想法:默认情况下,每个程序都有一个输入句柄和一个输出句柄,然后允许程序轻松地进行链接。这些被称为“标准”输入/输出。
Mooing Duck 2015年

Answers:


109

据我了解,管道是一个系统调用,它在两个进程之间共享一块内存,一个进程在其中写入数据,其他进程从中读取数据。

实际上,不涉及共享内存。读取器和写入器不共享其地址空间的任何部分,并且不使用任何显式同步。

读取和写入过程正在进行,read并且write系统调用与从文件中读取/写入文件时完全相同。这就是天才……创新:从应用程序程序员和用户的角度来看,(简单的)进程间通信和文件I / O可以以相同的方式处理的概念……。

管道设置完成后,操作系统(而不是应用程序代码或用户空间中的库)将负责缓冲和协调。透明地。


相比之下,在发明管道概念之前,如果需要进行“管道”处理,通常将有一个应用程序将输出写入文件,然后在完成后,运行第二个应用程序以从管道读取数据。文件。

另外,如果您想要一个真正的管道,则可以对两个应用程序进行编码,以建立一个(实际的)共享内存段,并使用信号量(或其他方式)来协调读取/写入。复杂...因此不经常执行。


34
“这就是天才……创新:进程间通信和文件I / O可以以相同的方式处理的概念” –正是这样。它允许您在程序之间进行进程间通信,而这些程序之间从来没有设计过通信,甚至不知道(需要)正在发生什么。
Guntram Blohm 2015年

6
还需要指出的是,将文件I / O用于IPC的原因主要是有用的,因为Unix是为文本处理而设计的-在程序之间流传输文本数据,实现了相对轻松的编写,这又意味着整个系统可以从相对简单的小型程序,这些程序在很长的简单操作链中将数据从一个流传输到另一个流。基本上,这意味着您可以使用相对灵活的语言来处理文本处理。
a安2015年

1
因此,“ Unix管道的实体”就是“ Unix的实体”:所有I / O(包括进程间通信,标准文件和其余文件系统对象)都作为文件处理。
Mark Hurd

另一个天才之处是UNIX在每个字节都被计数的时候提倡人类可读的文件结构...
EvertW '18

14

我认为,“管道”概念的天才在于使用的简便性。

您无需进行任何系统调用,分配内存,也没有什么复杂的。在外壳程序中,您使用单个字符:|。通过将简单(或复杂)工具组合到给定任务中,可以赋予非凡的力量。

进行一些日常工作,例如整齐地对文本进行排序。您可能有一个列出整个名称的命令。(对于我的示例,我将使用一个包含一堆名称的文件,由listofrandomnames.com提供。)使用管道,您可以执行以下操作:

$ cat names.txt
Sally Weikel
Dana Penaflor
Christine Hook
Shaneka Flythe
Almeda Crook
Freddie Lindley
Hester Kersh
Wanda Ruse
Megan Mauzy
Samuel Mancha
Paris Phipps
Annika Accardo
Elena Nabors
Caroline Foti
Jude Nesby
Chase Gordy
Carmela Driggers
Marlin Ostendorf
Harrison Dauber
$ cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100
Accardo, Annika     Hook, Christine     Ostendorf, Marlin
Crook, Almeda       Kersh, Hester       Penaflor, Dana
Dauber, Harrison    Lindley, Freddie    Phipps, Paris
Driggers, Carmela   Mancha, Samuel      Ruse, Wanda
Flythe, Shaneka     Mauzy, Megan        Weikel, Sally
Foti, Caroline      Nabors, Elena
Gordy, Chase        Nesby, Jude

这只是一个例子。有成千上万。有关通过管道使使用起来非常简单的其他一些特定任务,请参见本页的 “ Unix哲学”部分。


要强调此答案,请参见演示文稿的幻灯片4至9 ,“为什么Zsh比您的Shell更酷”。


我知道上面的命令包括一个UUOC。我让它保持立场,因为它是生成文本的任意命令的占位符。


3
小小的提示sort -u可以sort | uniq更快地完成工作。
Iwillnotexist Idonotexist 2015年

cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100您可能已经习惯了,但我一点也不认为它简单。特别是awk部分。
Federico Poloni 2015年

管道是简单的。我确实说过:“ ...将简单(或复杂)工具组合在一起对特定任务具有非凡的力量。”
2015年

5

因此,我尝试通过查找PDP-10 / TOPS-10手册对此进行了一些研究,以便弄清管道之前的技术水平。我发现了这一点,但TOPS-10很难用Google搜索。关于管道的发明,有一些很好的参考文献:对McIlroy的采访关于UNIX的历史和影响

您必须将其置于历史背景中。我们认为理所当然的现代工具和便利很少。

“一开始,汤普森甚至没有在PDP本身上编程,而是在GE-635机器上为GEMAP汇编器使用了一组宏。”(29)在GE 635上生成了纸带,然后在根据Ritchie的说法,直到PDP-7为止,“一个原始的Unix内核,一个编辑器,一个汇编器,一个简单的shell(命令解释器)和一些实用程序(例如Unix rm,cat,cp命令)就完成了。因此,该操作系统是自我支持的,无需编写纸带就可以编写和测试程序,并且继续在PDP-7本身上进行开发。”

PDP-7看起来像这样。请注意缺少交互式显示器或硬盘。“文件系统”将存储在磁带上。程序和数据的最大内存为64kB。

在这种环境下,程序员倾向于直接寻址硬件,例如通过发出命令来旋转磁带并一次直接从磁带接口读取字符来处理字符。UNIX为此提供了抽象,因此,它们不是将“从电传读取”和“从磁带读取”作为单独的接口,而是将它们合并为一个接口,并在管道中添加了“从其他程序的输出读取而不将临时副本存储在磁盘上”的重要信息。或胶带”。

这是麦克罗伊关于发明的grep。我认为在总结UNIX之前环境中所需的工作量方面做得很好。

“ Grep是为我发明的。我正在编写一个程序,通过语音合成器大声朗读文本。当我发明语音规则时,我会检查Webster词典中是否有可能失败的单词。例如,您如何处理有向图' ui”的发音有很多不同的方式:“ fruit”,“ guile”,“ guilty”,“ anguish”,“ intuit”,“ beguine”?我会将字典分解成适合ed有限缓冲和使用的片段一个全局命令来选择一个列表。我将通过对ed进行反复扫描来减少此列表,以查看每个建议规则的工作方式。”

“这个过程很繁琐,而且非常浪费,因为必须对字典进行拆分(一个人不能负担将拆分后的副本放在网上)。然后ed将每个部分复制到/ tmp中,对其进行两次扫描以完成g命令,最终把它扔掉,这也需要时间。”

“有一个下午,我问肯·汤普森(Ken Thompson)是否可以将正则表达式识别器从编辑器中取出,并制作一个单程程序来执行此操作。他说是的。第二天早上,我在邮件中发现了一个便条,宣布了一个名为grep的程序。就像一个咒语一样。当被问到这个好笑的名字是什么意思时,肯说它很明显。它代表了模拟的编辑器命令g / re / p(全局正则表达式打印)。”

将第一部分与cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100示例进行比较。如果您的选择是“构建命令行”而不是“在汇编器中专门为此目的编写程序”,那么值得构建命令行。即使需要花费几个小时阅读(纸张)手册也可以。然后,您可以将其写下来以备将来参考。


1

Pipes的天才在于它结合了三个重要的思想。

首先,管道是“协例程”的实际实现,这是康威(Conway)在1958年创造的一个术语,它很有希望,但在管道之前几乎没有实际使用。

其次,通过用shell语言实现管道,Thompson等人发明了第一种真正的“胶水语言”。

这两点允许可重用​​的软件组件以低级的,优化的语言有效地开发,然后粘合在一起以形成更大,更复杂的功能。他们称此为“大型编程”。

第三,使用与用于文件访问的系统调用相同的系统调用来实现管道,从而允许使用通用接口编写程序。这就为软件问题提供了真正通用的解决方案,该解决方案可以交互使用,可以使用文件中的数据,也可以作为大型软件系统的一部分使用,而无需对软件组件进行任何更改。无需编译,无需配置,只需执行几个简单的shell命令即可。

如果您希望了解学习过程,那么UNIX软件今天和40年前一样有用。我们不断地重新发明他们已经知道的东西,并为其建立解决方案。关键的突破是简单的Pipe。此后唯一真正的创新是80年代的互联网创建。戏剧性地,UNIX通过创建单独的API来破坏其实现。我们仍然要承受后果...哦,是的,在80年代后期,视频显示器和鼠标变得流行起来。但这是针对WIMP的。

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.