管道
管道是Unix中最古老的进程间通信的形式
我们把从一个进程连接到另一个进程的一个数据流称为一个管道
匿名管道
创建匿名管道的函数:
int pipe(int fd[2]);
头文件 <unistd.h>
参数含义:fd为文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码
写一个创建匿名管道的例子:
从键盘读取数据,写入管道,读取管道,写到屏幕
深入理解管道
从文件描述符的角度理解父子进程通过管道通信:
父进程创建管道:
fork后:
父进程关闭读端,子进程关闭写端:
看待管道可以像看待文件一样,符合Linux一切皆文件的思想
管道读写规则
管道的特点
只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可使用该管道。
一般,进程退出,管道释放,所以管道的生命周期随进程
一般,内核会对管道操作进行同步与互斥
需要双方通信时,需要建立起两个管道
命名管道
管道应用的一个限制就是只能在具有亲缘关系的进程间通信
如果我们想在不相关的进程之间交换数据,可以使用命名管道
命名管道是一种特殊类型的文件
创建命名管道
通过命令 mkfifo
或者通过相关函数int mkfifo(const char *filename,mode_t mode);
参数为路径和管道文件的权限
匿名管道和命名管道的区别:
匿名管道由pipe函数创建并打开。
命名管道由mkfifo函数创建,打开用open
FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义
实例
用命名管道实现A向B发送消息说她想吃什么
发送方程序:
接收方程序:
运行程序: