进程间通信:
什么是进程间通信
两个进程间进行消息传递
为什么进程间要通信
因为项目可能很大,进程之间通信,降低模块之间耦合度
大型的项目的模块化,是各个模块进程之间协同运行(数据传输,数据共享,通知事件,进程控制)
为什么进程间通信要操作系统提供接口:
因为进程间的独立性,进程间通信变得非常复杂,需要操作系统提供用于进程间通信的统一的接口,
来实现进程间的数据传输/数据共享/进程控制。
进程间通信的方式:管道(命名管道,匿名管道),共享内存,消息队列,信号量
操作系统如何能够让进程之间进行通信
给多个进程提供一个公共的都能访问到的媒介(这个媒介可以是缓冲区,也可以是文件)
操作系统提供进程间通信的场景稍有不同,因此提供的进程间通信方式也有多种,访问的媒介有所不同
多种方式各自有各自的特点:
-
管道(匿名/命名)(继承自unix)
-
system V标准(system 5) 系统调用接口
-
共享内存 (是进程间通信方式中最快的一种)
-
消息队列 (限制太多,属于已淘汰的东西)
-
信号量
-
-
posix标准 库函数
管道:用于在进程之间传输数据资源,实际上是一块缓冲区,是内核空间上的
操作系统为了让接口统一,对于管道这块缓冲区的操作,跟我们的io操作使用同一套接口
匿名管道于命名管道的区别
匿名管道用于父子间具有血缘关系的进程之间的通信,匿名管道创建的缓冲区在内核里没有标识符,其他进程没有办法通过标识符找到它进行通信
是因为操作系统在内核里创建了一块缓冲区,并且提供系统调用io接口,可以对管道进行操作,但由于管道属于半双工通信,因此提供两个文件描述符供用户操作选择数据流向,其他进程无法获取这个缓冲区的描述符,因此只能通过子进程pcb复制的方式获取到管道的描述符。
创建一个管道,返回文件的描述符,这时候创建一个子进程,子进程用于复制父进程,因此子进程也有相同的描述符指向内核空间相同的缓冲区,这是他们就可以进行通信了
命名管道具有文件可见性,可见于文件系统,因此所有的进程都可以通过打开这个文件,获取到内核管道这个缓冲区对应的描述符,因此命名管道可以用于同一机器上任意进程间通信
管道的特性:
-
管道是半双工通信(单向通信:一边发送,一边接受读取)
读写特性:
-
如果管道中没有数据,则read会阻塞,知道读取到数据
-
如果管道中数据满了,则write会阻塞,直到有数据被读取出去
-
如果管道的所有写端都被关闭,那么读端读完管道中的数据就会触发异常,退出进程
同步:对资源同一时间的唯一访问性 ()
互斥:对临界资源的时序可控性 (当前进程进行操作时不允许其他进程进行操作)
当对管道的读写数据大小不大于PIPE_BUF时,将保证数据读写的原子性(原子性:不可拆分)
特性:
-
半双工单向通信
-
读写特性
-
管道自带同步与互斥保护操作
-
提供字节流服务(体现在) 数据的传输较为灵活,但是有可能造成数据的粘连(本质是数据没有边界)缓冲区里的数据都在一块放着
-
管道的生命周期跟随进程:所有操作管道的进程结束,管道就会随之关闭
管道符的实现
匿名:ls | grep
mkfifo filename 用于创建一个命名管道
命名管道跟命名管道的各种特性都完全相同,(不包括仅限亲缘关系进程通信)
-
命名管道文件以只读方式打开,将阻塞,直到这个文件已写的方式打开
-
命名管道文件以只写的方式打开,将阻塞,直到文件以读的方式打开
-
以读写的方式打开,不会阻塞
哪种进程间通信方式速度最快,为什么?
共享内存,是进程间通信方式中最快的一种
共享内存的原理:先开辟一块内存,将内存映射到进程的虚拟地址空间,接下来直接通过虚拟地址对数据进行操作,而其他的进程间通信方式需要对数据进行内核空间与用户空间之间的两个数据拷贝
其他方式通信的原理:
比较可以看出,共享内存方式,少了两步从内核态到用户态之间进行数据拷贝的过程
共享内存的操作步骤:
-
创建共享内存,开辟一块内存
-
将共享内存映射到进程的虚拟地址空间
-
直接通知虚拟地址空间对数据进行访问操作
-
删除映射
-
删除共享内存
ipcs 指令用于查看当前系统共享内存,消息队列
消息队列:在内核里创建了一个队列结构,实现进程间的数据传输,消息队列传输的是一个个数据块,因为我们向队列里添加的就是这么一个数据块。传输的是有类型(是个整数)的数据块
类型可以用于区分数据是哪个数据,定义数据的优先级,区分数据对应的进程,也可以区分数据的功能
信号量 : 存在的意义:并不是为了资源的传递,而是为了实现对资源的管理
含义:是一个计数器+具有等待队列的计数器 ---用于对资源进行计数
获取一个资源,计数+1,如果没有资源,计数为0,为了获取资源因此死等
回收一个资源,计数+1,唤醒死等,唤醒的是信号量等待队列上的进程
功能就是等待与唤醒;用于实现进程间的同步与互斥
实现同步:不能唤醒则死等,别的进程资源回收后,计数为0,表示没有资源,代表不能操作,则死等;
计数+1,被唤醒才能进行操作 时序的可控性(等待与唤醒)
互斥:计数只有0/1,要么有资源可以进行操作,要不然没资源操作死等
别的进程拿走了资源,计数变为0,不能进行操作死等,意味着别的进程对资源操作期间,其他谁都无法对资源进行操作