1. 进程同步
- 有的进程间需要相互配合地完成工作,各进程的工作推进需要遵循一定的先后顺序
- 通过进程同步解决并发性带来的异步性
2. 进程互斥
-
同一时间段内只允许一个进程访问临界资源
-
理论实现思路
- 进入区:检查是否可以进入临界区,若可进入,需要“上锁”
- 临界区:访问临界资源的那段代码
- 退出区:负责“解锁”
- 剩余区:其他代码部分
-
遵循的原则
- 空闲让进:临界区空闲时,应允许一个进程访问
- 忙则等待:临界区正在被访问时,其他试图访问的进程需要等待
- 有限等待:要在有限时间内进入临界区,保证不会饥饿
- 让权等待:当进程不能进入临界区时,应立即释放CPU,防止进程忙等待
3. 进程互斥的软件实现方法
-
单标志法
-
算法思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予
-
伪代码模拟
int auth = 0;//授权进入临界区的变量 //a进程 while(auth != 0){ //处理临界资源 auth=1//权限转让 } //b进程 while(auth != 1){ //处理临界资源 auth=0//权限转让 } -
缺点:只能a→b→a→b→...轮流访问,如果a完全不访问临界资源,b一直都不能访问临界资源;违反了”空闲让进“的原则
-
-
双标志先检查法
-
算法思想:设置一个布尔型数组flag[],数组中各个元素用来标记各进程想进入临界区的意愿。每个进程进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则将自身对应的标志flag[i]设为true,之后开始访问临界区
-
伪代码模拟
boolean[] flag = {false,false};//进入临界区意愿的数组 //a进程 while(flag[1]){ flag[0] = true; //处理临界资源 flag[0] = false; } //b进程 while(flag[0]){ flag[1] = true; //处理临界资源 flag[1] = false; } -
缺点:进入区的”检查“和上锁不是原子操作,当a进程设置标志位的过程中,b进程也可以同时进来访问临界资源;违反了”忙则等待“的原则
-
-
双标志后检查法
-
算法思想:双标志先检查法的改版,先”上锁“,后检查
-
伪代码模拟
boolean[] flag = {false,false};//进入临界区意愿的数组 //a进程 flag[0] = true; while(flag[1]){ //处理临界资源 flag[0] = false; } //b进程 flag[1] = true; while(flag[0]){ //处理临界资源 flag[1] = false; } -
缺点:a、b进程同时设置完标志位,a、b进程检查都不通过,a、b进程都不能访问临界资源,违背了”空闲让进“和”有限等待“的原则
-
-
Peterson算法
-
算法思想:结合双标志法、单标志法的思想。如果双方都争着进入临界区,那可以让进程尝试让出进程
-
伪代码模拟
boolean[] flag = {false,false};//进入临界区意愿的数组 int auth = 0;//授权进入临界区的变量 //a进程 flag[0] = true; auth=1; while(flag[1]&&auth==1){ //处理临界资源 flag[0] = false; } //b进程 flag[1] = true; auth=0; while(flag[0]&&auth==0){ //处理临界资源 flag[1] = false; } -
缺点:虽遵循了”空闲让进“、"有限等待"和”忙则等待“三个原则,但是依然未遵循”让权等待“的原则
-
4. 进程互斥的硬件实现方法
-
中断屏蔽方法
- 利用”开/关中断指令“实现(与原语实现相同)
- 优点:简单、高效
- 缺点:不适用于多CPU;只适用于操作系统内核进程,不适用于用户进程
-
TestAndSet指令(TSL)
- 用硬件实现的,执行的过程不允许被中断,只能一气呵成。相比软件实现方法,TSL指令能把”上锁“和”检查“操作,实现原子性操作。
- 优点:实现简单;适用于多CPU环境
- 缺点:不满足”让权等待“原则
-
Swap指令
- 用硬件实现,执行的过程不允许被中断,只能一气呵成。
- 优点:实现简单;适用于多CPU环境
- 缺点:不满足”让权等待“原则
5. 信号量
- 信号量是一个表示系统中某种资源的数量的变量,本质就是一个变量。
-
用户进程可以通过使用操作系统提供的一对原语(P、V操作)来对信号量进行操作,比较方便实现了进程互斥、进程同步。
-
整型信号量
- 用一个整数型的变量作为信号量,表示系统中某种资源的数量
- 与普通整数变量相比,对信号量的操作只有三种:初始化、P操作、V操作
- 存在问题:不满足”让权等待“原则,会发生”忙等“
-
记录型信号量
- 用记录型数据结构(如剩余资源数、等待队列属性)表示的信号量
- P(S)操作请求资源,V(S)操作释放资源
6. 信号量机制实现进程互斥
- 分析并发进程的关键活动,划定临界区
- 设置互斥信号量mutex,初值为1
- 在进入区P(mutex)——申请资源
- 在退出区P(mutex)——释放资源
- 注意:对不同的临界资源需要设置不同的互斥信号量。P、V操作必须成对出现。
7. 信号量机制实现进程同步
- 分析什么地方需要实现”同步关系“,即必须保证”一前一后“执行的两个操作
- 设置同步信号量S,初始为0
- 在”前操作“之后执行V(S)
- 在”后操作“之前执行P(S)
8. 总结
- 重点:进程互斥的原则,可以往java多线程开发上方向上进行思考,例如:在多线程开发中,对于公共资源的访问,如果违背了”忙则等待“的原则,就会出现我们所说线程安全的问题。
- 重点:进程互斥的软件实现方法,需要理解其中思路,拓展开发思路
- 重点:信号量的类型,信号量解决了软硬件实现方法中都无法满足的”让权等待“原则,及时让出资源,进入阻塞态。
- 请各位大佬发现错误,能指导菜鸟小弟
- 菜鸟也想努力进大厂,加油