1.管道
1.1 匿名管道:
实现背景:
因为创建缓冲区没有任何标记,操作系统只是返回了文件描述符供进程操作,对于其他进程而言,就访问不到这个进程,无法实现进程间通信:
实现原理:
(在创建管道后,创建进程,)通过子进程拷贝父进程的PCB来获取到相同的文件描述符,进而对相同的管道进行操作,实 现进程间通信
注:若是没有创建管道,先创建进程,由于子进程是拷贝父进程的PCB,因此子进程就没有获得文件描述符
适用条件:
具有共同祖先的进程,(具有亲缘关系的进程间通信)
返回两个文件描述符的原因:
因为管道是单向通信的,然而目标操作文件系统无法替我们界定是读/写,因此 返回两个文件描述符,一个读,一个写,这样一来,进程的读与写操作由用户决定。注意,读的时候,写要关闭;写的时候,读要关闭。
创建匿名管道:
int pipe(int pipefd[2]);
pipefd:文件描述符数组,pipefd[0]是读端,pipefd[1]是写端
返回值:成功(0),失败(返回错误代码)
读写特性:
阻塞:为了完成功能发起一个调用,如果不具备完成条件,则一直等待。
管道为空,则读写数据(read)的时候会阻塞
管道满了,则写入数据(write)的时候会阻塞
当读写数据的大小不大于PIPE_BUFF(4096),读写是安全的。
临界资源:大家都能访问到的数据
同步:对临界资源的时序可控性。
互斥:保证临界资源的同一时间的唯一访问性,我访问的时候 你 不能访问
注意
如果管道的 写段 全部关闭,读完管道后的数据后read时候会返回0。
如果管道的 读端 全部关闭,write的时候会触发异常(会导致程序退出)
特性:
单向通信(半双工)、只适用于具有亲缘关系的进程间通信,管道的生命周期随进程,
管道自带同步与互斥,管道提供的是流式服务(数据传输是字节流传输)
1.2命名管道:
命名管道:
因为命名管道是可见于文件系统的 ,因此可以用于同一台机器上的任意进程间通信
匿名管道具备的特性,命名管道都具备,除了这些特性,命名管道还具备打开特性
创建命名管道的命令:mkfifo mkfifo()
int mkfifo(const char *pathname, mode_t mode);
pathname:管道文件名称
mode:管道访问权限
返回值:成功(0) 失败(-1)
int unlink(const char *pathname);
unlink():从文件系统中删除一个名字(目录项)
命名管道的打开特性:
如果以只读打开,会阻塞在open这里,等待有其他进程以写的方式打开
如果以只写打开,会阻塞在open这里,等待有其他进程以读的方式打开
如果以读写方式打开,那就不会阻塞
区别:任意间通信(命名管道,可见于文件系统),亲缘关系(匿名管道,缓冲区)