进程通信------管道

什么是管道

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:

进程通信------管道

进程通信------管道


运行结果:

        此代码运行结果目的是俩个终端的模拟交互,结果就不进行截图,想要观察结果,可自行运行。