为什么管道的容量有限?

Syd*_*.Ka 7 c unix system-calls

我读过管道需要具有有限的容量。但我不明白为什么。如果进程无限制地写入管道会发生什么?

Dai*_*Dai 8

这是由于缓冲。管道不是“神奇的”,管道并不能确保所有进程都以锁步方式处理每个单独的字节或字符。相反,管道缓冲进程间输出,然后传递缓冲区。这个缓冲区大小限制就是你所指的。在许多 Linux 发行版和 macOS 中,缓冲区大小为 64KiB

想象一下,有一个进程每秒向 stdout 输出 1GB 的数据——并且它通过管道传输到另一个每分钟只能在 stdin 上处理 100 字节数据的进程——考虑到这些千兆字节的数据必须去某个地方。如果有一个无限大小的缓冲区,那么您将很快填满拥有管道的任何操作系统组件的内存空间,然后开始分页到磁盘 - 然后磁盘上的页面文件会填满 - 这并不好。

通过设置最大缓冲区大小,输出进程将在缓冲区填满时得到通知,并且可以自由地处理该事件,但这是适当的(例如,如果它是随机数生成器,则暂停输出,如果它是网络监视器,则丢弃数据,通过崩溃, 等等)。

  • 从历史上看,管道缓冲区大小通常为 5 KiB;POSIX 规定最小管道缓冲区大小为 4 KiB。最初,机器的内存总量不到一兆字节(磁盘空间也没有多多少);他们无力储存所有东西。缓冲区大小是一种有效的速率限制机制(现在仍然如此)。 (2认同)

Joh*_*ger 6

撇开内部机制不谈,我怀疑问题背后的根本问题是术语之一。管道的容量有限,但传输的数据总量不受限制。

与一条物理管道的类比非常好:给定的水管具有由其长度、形状和内部横截面定义的特征内部体积。在任何给定的时间,它不能容纳比该体积更多的水,因此如果您关闭下游端的阀门,那么水最终(可能立即)停止流入其另一端,因为内部的所有可用空间 - 管道的容量——已满。然而,除非管道永久关闭,否则在其生命周期内可以通过多少水是没有限制的。