简单的说,管道就是将一个程序的输出和另外一个程序的输入连接起来的单向通道。
当进程创建一个管道的时候,系统内核同时为该进程设立了一对文件句柄(一个流),一个用来从该管道获取数据(read),另一个则用来做向管道的输出(write)。
事实上,在linux系统内核里,每个管道都是用一个inode节点来表示。
fork()的子进程自动继承了父进程打开的文件句柄。利用继承的句柄,就可以实现父/子间的通信了。
1. 由C来建立,使用管道
使用系统函数pipe()来建立管道,它只有一个参数:一个有两个成员的整型数组,用于存放pipe()函数新建立的管道句柄。其函数原型如下:
系统调用: pipe();
函数声明: int pipe( int fd[2] );
返回值: 0 on success
-1 on error: errno = EMFILE (no free descriptors)
EMFILE (system file table is full)
EFAULT (fd array is not valid)
注意: fd[0] 用来从管道中读, fd[1] 用来向管道中写
2.使用dup()函数
有时候我们需要将子进程当中的管道的句柄定向到标准I/O上去。这样,在子进程中使用exec()函数调用外部程序时,这个外部程序就会将管道作为它的输入/输出。这个过程可以用系统函数dup()来实现。其函数原型如下:
系统调用:dup();
函数声明:int dup(int oldfd );
3. 有名管道
为了解决管道不能提供非父子关系进程间通信的缺陷,在管道的基础上发展了有名管道。其存在于文件系统中的文件节点。