刚才具体分析了有名管道,有名管道是适用于任何两个进程间通讯的,那么无名管道也还是这样吗?无名管道和有名管道有什么区别吗?接下来我们来看看吧
无名管道:相对于有名管道而言,无名管道在使用时产生,不使用后释放,并不会在系统上留下蛛丝马迹。就因为它在使用前没有任何的标识,所以也只能适用于父子进程或者具有血缘关系的进程间通讯。
无名管道操作:
创建: int pipe(int fd[2]);
fd[0]代表管道的读取断,fd[1]代表管道的写入端打开: 打开就是与创建使用相同
读数据: read(fd[0], buff, size);
写数据: write(fd[1], buff, len);
关闭: close(fd[1]); close(fd[0])
注意:管道都是半双工通讯,而无名管道创建后,父进程在fork产生了进程后,两个进程分别有一对读写,所以要分别在父子进程中关闭读或写。
无名管道一些特点:
-
管道是半双工通讯,数据只能在某一时刻向一个方向流动,如果需要双方都同时通讯时,我们需要建立两个管道。
-
只能用于父子进程或者兄弟进程间(具有血缘关系的进程)通讯。因为其没有名字没有任何的标识符,使用时才创建,使用完释放,不留下任何信息。
-
无名管道也是在内存中开辟空间。
-
管道是基于队列实现的,有大小限制。
-
管道是一种特殊的文件,可以使用文件io函数来操作,但不能使用lseek函数来定位操作。
-
数据一旦被读走,便不在管道中存在,不可反复读取。
有关管道的一些问题:
管道的默认值大小是多少,能不能修改管道的大小?管道的内核实现(空间的开辟,读写操作偏移量的变化)?
1.管道的容量分为pipi capacity和pipe_buff,区别在于pipe_buff定义的是内核管道缓冲区大小。这个值的大小有内核设定,这个值仅需一条命令(ulimit -a)就可以查到;而pipi capacity指的是管道的最大值,即容量,是内核内存的一个缓冲区。
Pipe_buff:管道容量:sizeof(pie_buff)=512bytes*8=4kb
Pipicapacity:
当管道满时,write调用函数阻塞,直到有进程读走数据。通过测试大小为:65536