linux内核在哪里保存写入管道的数据

linux内核在哪里保存写入管道的数据,linux,pipe,Linux,Pipe,假设以下简单代码: #include <stdio.h> #include <unistd.h> #include <sys/types.h> main() { int fd[2]; pipe(fd); // ... write(fd, buf, VERY_BIG_NUMBER); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } #包括

假设以下简单代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

main()
{
    int fd[2];                
    pipe(fd);
 // ...               
    write(fd, buf, VERY_BIG_NUMBER);
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}
#包括
#包括
#包括
main()
{
int-fd[2];
管道(fd);
// ...               
写入(fd、buf、非常大的数字);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}
现在我的问题是:

  • 有人能解释一下写入将把数据放在哪里吗
  • 它是否写入位于用户空间或内核空间的某个缓冲区
  • 可以写入管道的最大长度是多少
  • 既然管道写入是阻塞操作,那么为了提高效率,内核不是什么都不做,等待读取器将数据直接传递给它吗

  • 有一个管道缓冲区,在Linux上通常为64KB。写入管道缓冲区。一旦它满了,
    write()
    syscall就会阻塞,直到管道的另一端耗尽缓冲区

    摘自:

    管道的容量有限。如果管道已满,则写入(2)将阻塞或失败,具体取决于是否设置了
    O_NONBLOCK
    标志(见下文)。不同的实现对管道容量有不同的限制。应用程序不应依赖于特定的容量:应用程序的设计应使读取过程在数据可用时立即消耗数据,从而使写入过程不会保持阻塞状态

    在2.6.11之前的Linux版本中,管道的容量与系统页面大小相同(例如,i386上的4096字节)。自Linux 2.6.11以来,管道容量为65536字节

    缓冲区位于内核空间中。管道是通过虚拟pipefs文件系统实现的。该文件系统的内核代码为每个
    pipe2()
    系统调用分配16个4KB页面,该缓冲区空间与为管道创建的inode相关联
    read()
    write()
    syscalls将数据复制到用户空间中或复制出用户空间。()

    如果对管道的写入小于4KB,则为原子写入。超过4KB的写操作可能导致页面错误,因此不再是原子性的。这意味着,如果写入大于4KB,则来自不同进程的多个写入可以交错进行


    另请参见:

    @rici我刚刚咨询了man 2,感谢您指出正确的页面。