赞
踩
Linux 管道对阻塞之前一次写操作的大小有限制。 专门为每个管道所使用的内核级缓冲区确切为 4096 字节。 除非阅读器清空管道,否则一次超过 4K 的写操作将被阻塞。 实际上这算不上什么限制,因为读和写操作是在不同的线程中实现的。
Linux 还支持命名管道。对这些数字的早期评论员建议我,为公平起见,应该比较 Linux 的命名管道和 Windows 的命名管道。我写了另一个在 Linux 上使用命名管道的程序。我发现对于 Linux 上命名的和未命名的管道,结果是没有区别。
Linux 管道比 Windows 2000 命名管道快很多,而 Windows 2000 命名管道比 Windows XP 命名管道快得多。
例子:
#include
#include
int main()
{
int n,fd[2]; // 这里的fd是文件描述符的数组,用于创建管道做准备的
pid_t pid;
char line[100];
if(pipe(fd)<0) // 创建管道
printf("pipe create error\n");
if((pid=fork())<0) //利用fork()创建新进程
printf("fork error\n");
else if(pid>0){ //这里是父进程,先关闭管道的读出端,然后在管道的写端写入“hello world"
close(fd[0]);
write(fd[1],"hello word\n",11);
}
else{
close(fd[1]); //这里是子进程,先关闭管道的写入端,然后在管道的读出端读出数据
n= read(fd[0],line,100);
write(STDOUT_FILENO,line,n);
}
exit(0);
}
总结:管道分为无名管道和有名管道,其中无名管道不属于任何文件系统,只存在于内存中,它是无名无形的,但是可以把它看作一种特殊的文件,通过使用普通文件的read(),write()函数对管道进行操作,
有名管道是有名有形的,为了使用这种管道,LINUX中设立了一个专门的特殊文件系统--管道文件,它存在于文件系统中,任何进程可以在任何时候通过有名管道的路径和文件名来访问管道。但是在磁盘上的只是一个节点,而文件的数据则只存在于内存缓冲页面中,与普通管道一样。
pipe是Linux中最经典的进程间通信手段,在终端里通常用来组合命令,例如“ls -l|wc -l”。它的作用很直观,就是使得前一个进程的输出作为后一个进程的输入,在概念上很符合“管道”的意思。
用管道实现“ls -l | wc -l“
《情景分析》上有这个例子的代码,我觉得很适合用来了解管道。这里假设终端对应的进程为PA,wc、ls是PA先后创建的两个子进程child_B与child_C。代码简化后抄录如下:
int main(){
int pipefds[2], child_B, child_C;
pipe(pipefds);
if (!(child_B=fork()){ //先创建“读”的一端,它要关闭“写”的的一端
close(pipefds[1]);
close(0);
dup2(pipefds[0], 0); //在执行系统调用execve后,child_B会释放0,1,2之外由父进程打开的文件,
close(pipefds[0]); //所以要把pipefds[0]复制到标准输入对应的文件句柄0
execl("/usr/bin/wc", "-l", NULL);
} //这里之后,A和B可以通过管道进行通信
close(pipefds[0]);
if (!(child_C=fork()){ //再创建“写”的一端,它要关闭“读”的的一端
close(1);
dup2(pipefds[1],1); //道理同前面
close(pipefds[1]);
execl("/bin/ls", "-1", NULL);
} //这里之后,B和C可以通过管道进行通信
close(pipefds[1]);
wait4(child_B, NULL, 0, NULL);
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。