操作系统(4)
操作系统(4)
如何分析同步与互斥:
(1)分析类型:纯互斥,纯同步,同步加互斥
(2)同步+互斥先做同步后做互斥
(3)分析存在几个运行主体
(4)站在每个运行主体的角度思考:它需要申请什么资源(条件),释放什么资源(结果)
(5)分析同步信号量的初值
(6)再做互斥/纯互斥:找到临界区,完成互斥
进程间的通信:
1.类型:
低级通信:只能传递状态和整数值(控制信息),包括进程互斥和同步所采用的信号量机制。
缺点是:传送信息量小,编程复杂
高级通信:可以传送任意数量的数据
包括:共享存储区、管道、消息。
直接通信:直接传递,类似于QQ的好友聊天(管道)
间接同行:发在双方进程之外的共享数据结构,比如QQ中的QQ群(消息队列)
2.共享存储区
与UNIX系统调用有关的有四个
(1)创建或打开共享存储区(\(shmget\)):创建新区或打开现有区,返回共享存储区ID
int shmget(key_t key,size_t size,int flag)
(2)连接共享存储区(\(shmat\)):连接共享存储区到本进程的地址空间,返回共享存储区首地址。
void *shmat(int shmid,const void *addr,int flag)
(3)删除共享存储区连接(\(shmdt\)):拆除共享存储区与本进程地址空间的连接。
int shmdt(void *addr)
(4)共享存储区控制(\(shmctl\)):对共享存储区进行控制
int shmctl(int shmid,int cmd,struct shmid_ds *buf)
关于死锁
一些结论:
(1)参与死锁的进程最少有两个
(2)至少有两个已经占有资源
(3)所有进程都在等待资源
产生死锁:
(1)申请不同类型的资源
(2)申请相同类型的资源(内存)
(3)PV操作不当
(4)对临时性资源的使用不加限制
死锁的两个方面 :
防死锁:预防、避免
预防:
破坏死锁的必要条件
必要条件:
1.互斥使用:没办法
2.不可抢占:处于等待状态的可以被抢占
3.请求和保持:(1)静态资源分配(一次性全给)(2)先释放已占有的再申请新资源
4.循环等待:资源有序分配:按照编号释放(递减)或申请(递增)
避免:
在系统运行过程中,对进程进行动态检查,根据检查结果决定是否分配。
PS:避免没有预防严格
安全状态和安全序列
安全状态:
如果存在一个有所有进程构成的安全序列${P_1,P_2...P_n}$,则处于安全状态
安全序列:
就是一个给定一个进程序列,按照这个序列执行进程,不会有问题。
显然,存在一个安全序列就可以保证是安全状态,那么不存在即是不安全状态,注意不安全状态不一定会导致死锁
银行家算法
(1)有资源请求,试探性分配
(2)找安全序列
(3)找到一个就行
PS:其实就是一个DFS回溯,这个问题就复杂的是主要是安全序列的正确性
解决死锁:
检测、解除
检测
不断监视系统状态
一旦发生死锁,解除死锁
如何检测死锁:
检测时机和方式:1.进程等待时检测死锁2.定时检测3.系统资源利用率下降
死锁的检测:
最常用的检测死锁的方法就是对资源分配图进行化简
资源分配图:
方框:资源类
方框中的原点:资源实例
圆圈:进程
分配边:资源实例->进程的一条有向边
申请边:进程->资源类的一条有向边
算法流程:
定义:P[i]为请求边均能立即满足顶点
while(找不到p[i]){
将P[i]的邻边全部删去
}
若所有的边都已被删除,则该图可完全被化简。
若不能被完全化简,则非孤立点的进程处于死锁状态(可以先想象,处于同一连通块的进程参与同一死锁)
环路与死锁:
如果资源分配图没有环路,则系统没有死锁
如果每一个资源类中只包含一个资源实例 ,则环路是死锁存在的充要条件。
解除
破坏循环等待条件:
从死锁进程中选择一个或者多个进程删除,剥夺他们资源给其他进程使用
选择的进程,一般从优先级、已经运行时间、已用资源考虑
综合处理:
三类资源:
(1)主存:抢占式
(2)作业资源(打印机、磁带、文件):银行家算法
(3)辅存:静态资源分配法