进程通信------管道
什么是管道
1>管道是UNIX中最古老的进程通信的形式。
2>一个进程连接到另一个进程的一个数据流(称为一个“管道”)。
常见管道实例:who | wc -l
匿名管道
#include<unistd.h>
功能:创建一个无名管道
原型:
int pipe(int fd[2]);
参数:
fd:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端。
返回值:成功返回0,失败返回错误代码
注:关于读端与写端其实不可以强行记忆,因为时间延长有可能会出现记忆错误,所以,对于读端的“0”我们可以将其看作是人的口,人的口是用来读的,故fd[0]就是读端;同理,我们可以将“1”看作是一支笔,笔是用来写东西的,故fd[1]为写端。
管道通信
管道(pipe)是连接读/写进程的一个共享文件,专用于实现进程之间的通信,因此,管道通信也称为共享文件通信,是发送进程(写进程)和接收进程(读进程)利用共享文件实现进程通信的一种方式,如图3所示。写进程是以字符流的方式将大量数据送入管道,并以先进先出的顺序单向传输数据;而读进程则从管道中接收数据。
管道通信是文件系统的基础上,引入通信协调机制来实现的。
注:读/写进程在管道中必须遵循以下几个准则:
1>读进程与写进程必须互斥地使用管道,即当写操作正在使用管道写入数据时,读进程则必须等待;而当读进程正在使用管道进行读操作时,写进程也必须等待。
2>读进程与写进程必须保持如下同步关系:当写进程把小于管道长度限制的字节数据写入管道后,写进程便睡眠,直到读进程把管道中的数据读走,才被唤醒,继续写数据;而当读进程读空管道时,读进程应睡眠,知道写进程把数据写入管道后,再将唤醒。
3>读数据与写数据必须以一定的方式知道对方是否存在,只有确定对方存在时,才进行通信;否则,如果对方不存在,就没有必要再交流信息。
由于管道通信是利用辅存来实现数据通信,因此,能够有效的进行大量信息的传输,且信息的保存长。但是I/O操作的次数较多,通信速度较慢,而且读/写进程之间需要相互协调,实现较为复杂。
命名管道
1>管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程通信.
2>如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被 称为命名管道。
3>命名管道是一种特殊类型的文件。
创建一个进程管道
1>命名管道可以从命令行创建,命令行方法是使用下面的命令:
$ mkfifo filename
2>命名管道可以从程序里创建,相关函数有:
int mkfifo(const char* filename,mode_t mode);
创建命名管道:
int main(){
mkfifo("fds",0644);
return 0;
}
命名管道和匿名管道的区别
1>匿名管道由pipe函数创建并打开。
2>命名管道由mkfifo函数创建,打开用open。
3>FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们的创建与打开的方式不同,一旦这些工作完成之后,它们具有相同的语义。
例1
运行结果:
例2:
运行结果:
例3:
运行结果:
此代码运行结果目的是俩个终端的模拟交互,结果就不进行截图,想要观察结果,可自行运行。