概述
管道通信分为无名管道、有名管道
管道通信的本质
不管是有名管道,还是无名管道,它们的本质其实都是一样的,它们都是内核所开辟的一段缓存空间。进程间通过管道通信时,本质上就是通过共享操作这段缓存来实现,只不过操作这段缓存的方式,是以读写文件的形式来操作的。
无名管道
如何操作无名管道
以读写文件的方式操作无名管道
1)有读写用的文件描述符(API部分讲)
2)读写时会用write、read等文件Io函数。
为什么叫无名管道
既然可以通过“文件描述符”来操作管道,那么它就是一个文件(管道文件),但是无名管道文件比较特殊,它没有文件名,正是因为没有文件名,所有被称为无名管道。
看下open的原型
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags);
返回值是文件描述符,或者-1(此时errno被设置)
无名管道的例子说明获取文件描述符未必非得使用open函数
无名管道特点
无名管道只能用于亲缘进程之间通信。
由于没有文件名,因此进程没办法使用open打开管道文件,从而得到文件描述符,所以只有一种办法,那就是父进程先调用pipe创建出管道,并得到读写管道的文件描述符。然后再fork出子进程,让子进程通过继承父进程打开的文件描述符,父子进程就能操作同一个管道,从而实现通信。
API
函数原型
#include <unistd.h> int pipe(int pipefd[2]);
功能
创建一个用于亲缘进程(父子进程)之间通信的无名管道(缓存),并将管道与两个读写文件描述符关联起来。无名管道只能用于亲缘进程之间通信。
参数
缓存地址,缓存用于存放读写管道的文件描述符。从这个参数的样子可以看出,这个缓存就是一个拥有两个元素的int型数组。
1)元素[0]:里面放的是读管道的读文件描述符
2)元素[1]:里面放的是写管道的写文件描述符。
特别需要注意的是,这里的读和写文件描述符,是两个不同的文件描述符。
从这里大家也可以看出,并不是所有的文件描述符,都是通过open函数打开文件得到的。这里无名管道的读、写文件描述符,就是直接在创建管道时得到的,与open没有任何关系。而且这里也根本没办法使用open函数,因为open函数需要文件路径名,无名管道连文件名都没有,所以说根本就没办法使用open来打开文件,返回文件描述符。
返回值
成功返回0,失败则返回-1,并且errno被设置。