进程间通讯的意义很多书上都有说,总之是非常重要的一部分,就不多啰嗦了,简单来说是为了完成进程间的协作功能。
写了65536个a后就阻塞住了,65536个字节=2^16 byte=2^6 kb=64k
然而进程间的通讯方式也不少,信号,信号量,管道,共享内存.....
今天先来说说管道中的有名管道。当然有
有名管道自然也有无名管道。至于他俩的区别,我们暂且记着有名管道是可以让同一台计算机上的任意两个无关系的进程通信。而
无名管道则是必须需要通信的进程间存在关系,比如父子进程。
有名管道的原理是什么呢?有名管道的管道具体在计算机的哪个地方呢?
请看下面这张示意图
有名管道是在进程使用管道时在系统内存上开辟的一段空间,如果A需要给B传递某些信息,A进程就给那段开辟的空间里写入数据,而B也从那段开辟的空间里读取数据,并且重要的一点是管道保存的数据是未被进程读的,或者说B读数据就好比循环队列,读过的数据就出队消毁了,不会停留在管道中被重复读取,就好比接电话,音过了就过了,不会为你保存一份录音 供你重复听。
既然是内存上开辟的空间。那就说明管道不会占用磁盘的空间。
管道文件好比是一个标记。供使用这个标记的进程们在运行时 使用同一段指定的内存 进行通讯,读写数据。
创建管道有两种形式
一是在命令窗口使用
mkfifo 管道名
二是代码中调用系统
函数
mkfifio();
之后的操作就把管道看作文件,使用文件操作就好
打开:
open
写数据:
write
读数据:
read
关闭:
close
值得注意的是对管道的一些文件操作函数会阻塞运行。
何为阻塞运行?就是
函数调用以后并不会立即返回,需要等待某些条件的发生才会返回。
如果一个进程以只写方式打开一个管道文件,
open就
会阻塞运行,直到一个进程以读方式打开文件该管道文件,
open
才会返回,进程才会继续执行。
这样设计的目的何在?我们都知道管道是为了传输数据,如果没有要传给的对象,也就是没有其他进程读取管道内容,那么给管道标记的那段内存写数据将没有意义,浪费内存空间,而且我们之前也说了管道的那段内存是循环队列,只有读数据才会把内存的数据出队,没进程使数据出队,一个劲儿的写,势必也是不好的。当然的,一般不会出现管道写入数据把内存挤爆的情况,因为管道是有默认大小的。
read也会阻塞运行。如果其他进程没有给管道写入数据 或者 写入数据的进程全部关闭了。read当然没有读的意义了,就会阻塞运行。
write虽然也会阻塞运行,但阻塞条件比较难达成,就是管道写满的情况。
之前也说了管道是有大小的,会写满,那么它究竟有多大呢?
写个简单的代码测试一下
写了65536个a后就阻塞住了,65536个字节=2^16 byte=2^6 kb=64k