![使用 FIFO 与临时文件或管道的目的是什么?](https://linux22.com/image/130224/%E4%BD%BF%E7%94%A8%20FIFO%20%E4%B8%8E%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6%E6%88%96%E7%AE%A1%E9%81%93%E7%9A%84%E7%9B%AE%E7%9A%84%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
来自APUE
FIFO 可用于在一系列 shell 命令中复制输出流。这防止将数据写入中间磁盘文件(类似于使用管道来避免中间磁盘文件)。
但是管道只能用于进程之间的线性连接,而 FIFO 有名称,因此可以用于 非线性连接。
考虑一个需要处理两次过滤输入流的过程。
mkfifo fifo1 prog3 < fifo1 & prog1 < infile | tee fifo1 | prog2
我们创建 FIFO,然后在后台启动 prog3,从 FIFO 读取数据。然后我们启动 prog1 并使用 tee 将其输入发送到 FIFO 和 prog2。
FIFO 如何“在一系列 shell 命令中复制输出流”?这不是用
tee
FIFO 来完成的吗?在示例中,
mkfifo fifo1
在当前目录中创建一个文件,并且fifo1
似乎可以替换为常规文件。那么 FIFO“防止将数据写入中间磁盘文件”的意义何在呢?进程之间的“线性连接”和“非线性连接”是什么意思? FIFO可以用于非线性连接,而管道只能用于进程之间的线性连接,这意味着什么?
谢谢。
答案1
APUE 说“先进先出可以使用复制输出流”,它并没有说 FIFO 实际上复制了输出流。正如您所指出的,复制是
tee
在示例中完成的。mkfifo
创建一个 FIFO,它在包含的目录中作为“文件”可见;但写入 FIFO 与写入文件不同,因为数据永远不会到达磁盘。管道,无论是命名管道还是其他管道,都不提供数据存储,而是提供通信通道;如果没有接收器,管道的写入端无法写入数据,管道只是传递数据,而不存储数据。 (在大多数系统管道上是由小型内核缓冲区支持,以提高性能,但这是一个实现细节。)进程之间的线性连接是可以表示为线性图的管道。在示例中,您可以将最后一行表示为
infile → prog1 → tee fifo1 → prog3
这是线性的,但如果你尝试表示整个链,减少处理元素,你需要
infile → prog1 → prog2 → prog3
这是非线性的(图中有一个节点 ,
prog1
它有两个退出节点)。