进程间通信背景:
每一个进程想要访问物理内存,都是通过访问进程虚拟地址空间当中的虚拟地址进行访问,访问时,通过各自的页表结构,造成了每一个进程和每一个进程的数据独立,由于进程独立性的存在,进程运行时不会相互干扰,但是造成了进程与进程之间相互协作的难点。由此学习进程间通信本质就是为了进程与进程交换数据时使用
进程通信的前提是不同的进程能看见同一份资源
进程间通信的方法:
- 管道
- 共享内存
- 消息队列&信号量
- 信号
管道符号:|
ps aux|grep xxx
ps:本质都是可执行程序
grep:可执行程序
将ps aux的输出内容通过管道|作为grep xxx的输入内容
管道的本质:
管道在内核当中是一块缓冲区,供不同的进程进行读写的缓冲区
管道的接口:
int pipe (int pipefd[2]);
pipefd:数组,输出型参数。
pipefd[0],pipefd[1]是pipe函数进行填充的,参数当中保存的是文件描述符,两个文件描述符分别对应管道的读写两端。
pipefd[0]:管道的读端
pipefd[1]:管道的写端
返回值:0代表创建成功,-1表示创建失败
管道的特性:
- 管道是半双工通信的,数据流只能从写端流向读端
- 匿名管道在内核创建出来的缓冲区是没有标识符的,导致了其他进程没有办法直接找到这个缓冲区,但是创建的进程可以通过读写两端的文件描述符进行操作
- 匿名管道只支持具有亲缘性关系的进程(父子进程)进行进程间通信
- 在进行父子进程通信时,父进程先创建管道再创建子进程,此时子进程的文件描述符表中才会有匿名管道的读写两端的描述符
- 当文件描述符保持基础属性(阻塞),一直调用write将管道写满后,write函数就会阻塞
- 管道的生命周期是跟随进程的
- 管道的通信是面对字节流的,写入与读取的次数并不是一一匹配的