进程间通信:讲的是操作系统为用户提供的几种进程间的通信方式
概念:进程间通信其实就是多个进程之间进行数据交互
问题:进程间通信为什么不能直接进行数据交互,需要使用系统提供的方式?
原因:进程之间是具有独立性的,每个进程都有自己的虚拟地址空间,访问数据的时候都是通过自己的虚拟地址进行访问的,一个进程将自己的某个变量的空间地址(虚拟地址)交给另一个进程,另一个进程是无法访问的(例如,把两个人放在两个真空空间,这时候两个人说话对方听不到,无法形成实质性通信)
1.管道
生活资源一般也都是管道传输:自来水管道等
管道的特性:半双工通信
管道的本质:操作系统给进程之间提供进程间通信的方式,本质其实都是提供了一个空间的交叉点,都能访问,在我们程序中,管道其实是内核中的一块缓冲区(就是一块内存,多个进程通过访问同一块缓冲区来实现数据传输)
管道分类
管道本质是内核中的一块缓冲区,但是Linux操作系统中,一切皆文件,将管道当作文件处理
匿名管道没有标识符,无法被其他进程找到,所以无法进行通信,这时候只能通过创建子进程的方式进行,子进程复制了父进程,也就复制了父进程所拥有的操作语柄,通过语柄可以访问到这个管道
匿名管道就像是家族财产,只有同一个家族的人才有操作句柄,子进程复制父进程,会复制到同一个管道的操作句柄,因此能够访问同一个管道
操作句柄:文件描述符
通过文件描述符这个下标,就能找到管道的描述信息,进而找到管道进行操作
2.管道操作
int pipe(int pipefd[2]);
功能:创建一个管道,并通过参数返回管道的两个的操作句柄
管道特性
管道中如果没有数据,则read从管道读取数据会阻塞,直到有数据了,读取到数据后才能返回
如果管道中数据满了,则write继续向管道写入数据会阻塞,直到管道中有剩余空间才行
管道的 所有读端被关闭,则继续向管道写入数据会导致进程崩溃退出
管道的 所有写端被关闭,则read从管道读取完所有数据后不再阻塞,而是返回0
ps -ef | grep pipe1
| 管道符:连接两个命令,将前边命令的输出结果,交给后边命令进行处理
命名管道
本质:内核中的一块缓冲区,但是有名字,能够被其他进程找到,因此可以用于同一主机上任意进程间通信
命名管道的通信原理,就是一个进程创建一个命名管道的名字
多个进程通过相同的管道名字,打开同一个管道,访问同一块核心缓冲区
命名管道的名字:是一个可见于文件系统的管道文件
接口:
int mkfifo (char *pathname, mode_t mode);
pathname:管道文件名称
mode: 管道文件的访问权限
返回值: 成功返回0, 失败返回-1;
命名管道独有的特性:
若以只读的方式打开管道文件,则会阻塞,直到管道被任意进程以写的方式打开
若以只写的方式打开管道文件,则会阻塞,直到管道被任意进程以读的方式打开
因为一个管道如果不构成同时读写具备,就没有必要开辟缓冲区
3.共享内存
作用:用于多个进程之间的数据共享
特性:最快的进程间通信方式
原理:开辟出一块物理内存,然后,多个进程将这块内存都映射到自己的虚拟地址空间中,通过虚拟地址直接访问物理内存中的数据
接口
4.消息队列 (了解)
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法
每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值
特性方面:
IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核
5.V信号量 (了解)
信号量主要用于同步和互斥的,下面先来看看什么是同步和互斥。
进程互斥
由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥
系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。
在进程中涉及到互斥资源的程序段叫临界区
特性方面:
IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核