Linux进程间通信之一:无名管道PIPE

基本概念

无名管道是一种特殊类型文件。内核资源对应一段特殊内存。管道的数据流是单向的。

命令ulimit -p 查看管道最大值限制,默认为8*512Byte=4KB。由limit.h的宏PIPE_BUF定义。

头文件:#include <unistd.h>

原型:int pipe(int pipefd[2]);

若执行成功,pipefd内将存储两个文件描述符,指向管道的两端(pipefd[0]读,pipefd[1]写);
若执行失败,返回值为-1。

读写管道用系统调用readwrite,默认以阻塞方式读写。

工作原理

示例代码

实现管道操作ls /home/tao|sort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc,char *argv[])
{
int fd[2];
if(pipe(fd)==-1)
{
perror("pipe");
exit(-1);
}
if(fork() == 0)//child process.用于sort
{
dup2(fd[0],0);
close(fd[1]);
execlp("sort","sort",(char *)0);
}
else
{
if(fork()==0)//child process.用于ls
{
dup2(fd[1],1);
close(fd[0]);
execlp("ls","ls","/home/tao",(char *)0);
}
else
{
close(fd[0]);
close(fd[1]);
wait(NULL);
wait(NULL);
}
}
return 0;
}

程序说明:主进程分别fork了两个子进程,主进程产生的管道由两个子进程共享使用(管道是文件,根据进程fork的原理,父子进程共享打开的管道文件)。一个子进程执行ls,用dup2将标准输出重定向到管道写端fd[1],另一个子进程执行sort,dup2将标准输入重定向到fd[0],于是它从管道读端fd[0]获取需要sort的数据。这样就实现了主进程的两个子进程的通信。

执行结果:和执行 ls /home/tao|sort一模一样。

可以看出,为了共享同样的文件描述符,无名管道适合这种亲缘关系接近的子进程之间通信。