假设以下简单代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
int fd[2];
pipe(fd);
// ...
write(fd, buf, VERY_BIG_NUMBER);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题:
Joh*_*ica 10
Linux上有一个通常为64KB的管道缓冲区.写入管道缓冲区.一旦它充满,write()系统调用就会阻塞,直到管道的另一端排出缓冲区.
摘自pipe(7)手册页:
管道的容量有限.如果管道已满,则write(2)将阻塞或失败,具体取决于是否
O_NONBLOCK设置了标志(见下文).不同的实施方式对管道容量有不同的限制.应用程序不应该依赖于特定的容量:应该设计一个应用程序,以便读取过程一旦可用就会消耗数据,这样写入过程就不会被阻止.在2.6.11之前的Linux版本中,管道的容量与系统页面大小相同(例如,i386上的4096字节).从Linux 2.6.11开始,管道容量为65536字节.
缓冲区位于内核空间中.管道通过虚拟pipefs文件系统实现.此文件系统的内核代码为每个pipe2()系统调用分配16个4KB页面,并且该缓冲区空间与为管道创建的inode相关联.read()和write()系统调用将数据复制到用户空间和从用户空间复制数据.(来源)
如果它们低于4KB,写入管道是原子的.超过4KB的写入可能会导致页面错误,因此不再是原子的.这意味着如果写入大于4KB,则可以交叉来自不同进程的多个写入.
另请参见: 管道缓冲区有多大?