在 Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。
有两个 file 数据结构,但它们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,而另一个是从管道中读出数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。
对于管道的容量,我们可以写一个程序来测试,读端不读而写端一直写:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
int main()
{
int mypipefd[2];
int fd = pipe(mypipefd); //创建管道
if(fd < 0) //管道创建失败
{
perror("pipe");
return 2;
}
pid_t id = fork(); //创建子进程
if(id < 0)
{
perror("fork");
return 2;
}
else if(id == 0)
{
close(mypipefd[0]); //关闭子进程的读功能
long long count = 0;
char *msg = "h";
while(1) //写端一直写
{
write(mypipefd[1],msg,1); //子进程写
printf("count=%ld\n",++count);
}
}
else
{
char _msg[128];
while(1)
{
memset(_msg,'\0',sizeof(_msg));
}
}
}
运行结果:
由此可知,管道的容量为count = 65536,4KB。