管道中的命令之间有哪些缓冲区?

What buffers are between commands in a pipeline?

我以为是 1 个缓冲区,但现在我想到它可能是 2 个。

我的意思是在管道中:

cmd1 | cmd2

cmd2 的输出可能是例如行缓冲,那里没有管道。这应该是像fwrite()这样的libc FILE *流函数管理的缓冲区,或者这个缓冲区也被write(3)使用?但是,我只记得 pipe(7) 谈到了显然在内核中控制的管道缓冲区的大小。

stdin 也被缓冲了吗?是否有 3 个缓冲区,1 个在内核 space 中,2 个在用户 space 中?

我之前认为 read(2) 在管道缓冲区为空时挂起,但是当 stdin 不是管道而是终端时,我没有管道缓冲区,对吗?如果它没有自己的缓冲区,它会根据 stdin 是管道还是终端还是常规文件来检查不同的缓冲区?

编辑:将问题中的 "how many" 更改为 "what"。我希望这不是太大的变化。我想知道缓冲区是什么,而不仅仅是一个数字。

Is stdin buffered, too? Are there 3 buffers, 1 in kernel space and 2 in user space?

是的,一般这里可能有 3 个缓冲区:一个用于 cmd1 stdout,一个用于 cmd2 stdin,内核中有一个 space.

I previously thought that read(2) hung when a pipeline buffer was empty, but when stdin is not a pipe but rather a terminal, there i no pipeline buffer, right?

当没有输入时,read 系统调用会阻塞,但这与 stdio 缓冲没有任何关系

内核缓冲区存在不管输入是否来自终端(内核一次传输一个字符效率非常低)。

默认 stdio 库不会缓冲终端输入,但应用程序可以通过显式调用来更改它,例如setvbuf.

博客 post 有更多详细信息 here