有名管道通信

来源:互联网 发布:mysql 添加分区出错 编辑:程序博客网 时间:2024/06/03 19:58
多个进程间数据相互交换,即进程间通信有以下方式:
信号通信、管道通信(有名管道通信和无名管道通信)、信号量通信、消息队列通信、共享内存(或共享储存)、套接字通信。


如果进程A输入“hello world”,进程B读取并输入,有什么方式可以做到呢?之前学过父子进程,在父子进程之间全局变量、栈区变量、堆区变量都是不共享的,但是文件偏移量是共享的,文件可以做到但是有缺陷:1、不能同步,也就是说当前文件正在写入数据,但是读取可能读取不到;2、I/O操作慢。接下来也就提到我们今天的主要内容——有名管道通信。


有名管道通信应用于任意两个进程之间的数据的单向传递。


如上图所示,在内存上开辟一块空间,也就是管道,进程A把内容写入,使进程B可以读取。由于管道是半双工通信(数据只能在一个方向上流动),所以同一时刻只能是A写B读,或者B写A读。既然是在内存上开辟空间,也就是说不会占用磁盘空间,我们创建管道文件后在目录树中有一个标示,但实际不占用内存空间,仅占用一个inode结点。而且数据缓存在内存上效率更快,这也是优势之一。


我们在学习文件类型时有个管道文件,这里的管道其实也就是文件,那它的一些操作和文件操作是一样的。具体来看,文件的的创建有2种形式:命令方式 mkfifo;函数方式 mkfifo()。打开open,读数据read,写数据write,关闭close。


我们通过写两个简单的进程,就会发现只执行其中一个不显示打开失败也不会显示成功,一直在等待。这里也就是我们要说的阻塞运行函数。


1、函数执行以后并不会立即返回,需要等待某些条件才会返回。open在操作管道文件时为阻塞运行函数。如果一个进程以只写打开一个管道文件,open会阻塞运行,直到有一个进程以读方式打开管道文件,open才会返回,进程才会接着执行。如果一个进程以只读打开一个管道文件,open会阻塞运行,直到有一个进程以写方式打开管道文件,open才会返回,进程才会接着执行。这里也不难理解,如果我写数据进去而没有人来读,也就没有意义。

2、read也会阻塞运行,直到数据写入或所有的写端全部关闭才会返回。当管道满的时候write也会阻塞。


相比于文件实现,里边有内容就读取,没有就返回,管道阻塞运行等待其写入也是其优势之一。


这里还有一点就是,read读取数据之后就会清空已读数据,这样管道就类似于循环队列,不断写入读取。




原创粉丝点击