如果我有一根管道:
process1 | process2
进程 1 非常快地生成数千兆字节的数据,但进程 2 需要通过网络发送该数据,因此速度要慢得多,执行以下操作:
- 减慢process1的执行速度?;或者
- 将数据缓冲在某处,直到进程 2 可以读取它?
如果数据正在缓冲,是由内核缓冲的吗?是在内存中,还是在磁盘上?这个缓冲区有多大?当缓冲区溢出时会发生什么?
答案1
较慢的过程限制了较快过程的速度。管道是一个缓冲区(大小为 512 到 64k 字节,具体取决于内核以及进程使用 fcntl(2) 操作进行的任何调整),位于通过write()
调用将字节放入缓冲区的进程与从缓冲区中取出字节的另一个进程之间。带有呼叫的缓冲区read()
。
write()
和调用都read()
将控制权传递给内核。因此,如果读取进程调用read()
空管道缓冲区,则内核不会从该缓冲区返回,read()
直到另一个进程放入字节(或关闭其标准输出文件描述符)。另一方面,如果写入进程调用write()
完整的管道缓冲区,则内核不会将新字节添加到缓冲区并从缓冲区返回,write()
直到另一个进程拉出字节(或关闭其标准输入文件描述符)。
因此,效果是较快进程的性能受到较慢进程性能的限制。内核不允许管道缓冲区溢出,也不允许下溢。